system
System 一个用来处理数据的系统(可以理解为Unity的一个自定义组件,里面只有方法,没有任何数据)
ecs是将数据和逻辑拆分的架构思想,而逻辑部分就体现在system。
假设我们有一个英雄出生死亡的system。
local tiny = require('tiny')
local Hero = require('Hero')
local _M = class()
tiny.system(_M)
_M.filter = tiny.requireAll("heroID")
function _M:init(_roles)
self.roles = _roles
end
function _M:onAdd(e)
for k,hero in pairs(self.roles) then
if hero.id == e.heroID then
hero.status = e.isAlive
break
end
end
end
return _M
只需要传入一个英雄id和英雄状态标志(“生”或“死”)时,system就能去修改英雄状态。英雄其他相关的状态,如当前的动画,英雄身上的特效。这个system不需要关心。system里也没有数据(血量,战力,怒气值...)。但是system里有个表roles,保存所有英雄的引用,那么这个是数据吗?
system 拆分
关于ecs的拆分依据,以unity为例,个人建议是一个unity的component组件为一个system。比如我要控制一个英雄的位置、方向、动画。依据component(transform和animator)我可以拆分成两个system。transform的system控制位置和方向,animator的system控制播放的动画。
当然,也有例外。比如,我需要用system实现展示英雄的血量(血量展示包含一个image的进度条,一个text显示数值文本)。如果按照上述说法,那么system必定拆为两个。但是这个进度条和文本一定是绑定的,一起修改。那么有必要拆开成两个system吗?
system分层
假设我们要表现一个完整的英雄加载到战斗场景中,一个完整的英雄包含英雄的模型、英雄血量和名字的UI文本,还要有个登场特效。拆分开就是先展示登场特效,特效播放到一半英雄模型出现,随后UI文本出现。
当我们发送entity的时候,我们关心的是什么?假设模型和血量以及名字都是读取配置初始好了的,那么我们发送entity的时候只需要关心是哪个英雄就可以,即只需要英雄的id。
所以我们entity就是
local Entity = class()
function Entity:init(id)
self.id = id
end
return Entity
而出生的system需要再次分发entity到对应的ui system和模型system
网友评论