ECS架构笔记

ECS由三个部分构成:
Entity:实体、个体。由多个component组成
Component:组件、数据。由数据组成
System:系统。由逻辑组成

Component:

组件Component是一个基类,有几百个子类,每个子类都有System执行Behavior时所需的成员变量。这里的多态是用来重写Create,以及使用虚析构函数管理声明周期,帮助回收垃圾。另外可能有访问内部状态的helper函数,除此之外Component不应该有Behavior。

class Component{
virtual void Create(resource* m_resource);
virtual ~Component();
}

Entity:

ECS架构笔记
一个Entity其实像是一个对象,可以代表游戏世界中的任意对象,而其内部包含了若干个Component,拥有全局唯一的EntityID,用于标识Entity本身,ID是一个32位无符号整数。

class Entity{
 unsigned int ID;
 vector<Component> components;
}

System

而System则是系统,是行为,用来制定游戏规则。System本身没有数据,只有方法。在应用中,System之间不可以直接通信,并且一个System只关心某一个固定的Component组合,这个组合称为tuple。
**使用一个System的条件:**System会遍历所有Entity,若Entity当中,拥有System中tuple指定的所有Component,则对该Entity进行处理。
System本身并不关心Entity是谁,它只关心Entity中包含的component。
本人猜想的System和tuple的例子:

class System{
public:
  virtual void update(f32 timeStep)=0;
  virtual ~System();
}
class HitSystem:public System{
vector<Component> tuple;
public:
 virtual void update(f32 timeStep){//其实这段代码干了什么我真不清楚
   for(DerpComponent* d:ComponentItr<DerpComponent>(m_admin)){
    d->m_timeAccu+=timeStep;
    if(d->m_timeAccu>d->m_timeToHerp) this->HerpYourDerp(d,d->Sibling<HerpComponent>());
  }
 }
  for(Entity &entity:world.entitys)
   {
      if(/*entity中有tuple中的所有component*/)
      {//对应处理:
      }
   }
 }
}

实际上的System和tuple的例子:

//tuple
struct PhysicsTuple
{
 DynamicPhysicsComponent* m_dynamicPhysics;
 TransformComponent* m_transform;
 ContactListComponent* m_contacts;
}
//system
void PhysicsSystem::Tick(f32 timeStep)
{
   IPhysicWorld* pw=GetPhysicsWorld();
   pw->Update(timestep);
   //write transeforms of dynamic physics objects
   for(PhysicsTuple& t:getPhysicsTuples())
   {
    IPhysicsProxy* proxy=pw->GetProxy(t.m_dynamicPhysics->m_proxy);
    CopyTransform(t.m_transform,proxy);
    CopyContacts(t.m_contacts,proxy);
   }
}

但是这里我有一点疑问,每一次行为如果需要遍历所有的Entity,那么其复杂度就是tuple的component个数乘以Entity个数乘以Entity内component的个数,这个复杂度会不会很大?

World

(图来自视频截图)
ECS架构笔记
World即是图中的EntityAdmin,其中包含了所有System,用哈希表存的Entity,以及所有Component。 而World里面有Update函数。

void EntityAdmin::Update(f32 timeStep)
{
 for(System* s:m_systems) s->Update(timeStep);
}
上一篇:元组&集合


下一篇:30. 派生不可变类型