# ECS_Try **Repository Path**: XTST/ECS_Try ## Basic Information - **Project Name**: ECS_Try - **Description**: ECS架构试水系列 - **Primary Language**: C# - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2017-07-27 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #ECS_Try ECS架构试水系列 #一个采用架构封装的例子: ... var res = ECSWorld.CreateEntity().AddComponent().Init(1, 2, 3) .entity.GetComponent().ToString(); Console.WriteLine(res); ECSWorld.AddSystem(); Thread UpdateThread = new Thread(ECSWorld.UpdateOnce); UpdateThread.Start(); UpdateThread.Join(1000); Thread.Sleep(1);//等待更新 res = ECSWorld.GetEntities(ECSWorld.DefaultMaskContainer[typeof(PositionComponent)])[0] .GetComponent().ToString(); Console.WriteLine("After Update:" + res); ... #一个自己封装的例子: ... Console.WriteLine("ECSBase test"); EntityAdmin world = new EntityAdmin();//生成一个世界 Entity entity = world.CreateEntity();//申请一个实体 int newId = entity.EntityID; entity.AddComponent();//给他添加一个组件 entity.GetComponent().x = 1; entity.GetComponent().y = 1;//定义一下组件的值 var cb = entity.GetComponent(); cb.z = 1; Entity final = world.GetEntity(newId); Console.WriteLine(string.Format("{0} \n{1}", entity.GetComponent().ToString(), final.GetComponent().ToString()) ); Console.WriteLine(world.GetEntity(newId).GetComponent()); world.AddSystem(); world.UpdateOnce(); Console.WriteLine(world.GetEntity(newId).GetComponent()); ... #可用版本 ECS.sln->ECSBase #接口说明 ##ECSWorld 最大的管理类,通过DefalutAdmin管理ECS架构下的所有实体,单例组件和系统。 ### static funcs #### Entity ECSWorld.CreateEntity() 在*ECSWorld*中新建并注册一个实体,返回这个实体。 var newEntity = ECSWorld.CreateEntity(); newEntity.AddComponent(); #### int AddEntity(Entity newEntity) 将*newEntity*注册到ECSWrold中,返回它在ECSWorld中的ID。 var newEntityID = ECSWorld.AddEntity(newEntity); #### void DeleteEntity(int entityId) 将ID为*entityId*的实体从ECSWorld中解除注册(*实体仍然在内存中存在*,引用仍然可用,要完全删除需要手动实现。) ECSWorld.DeleteEntity(entityId); #### Entity GetEntity(int entityId) 从ECSWorld中获取ID为*entityId*的实体。 ECSWorld.GetEntity(entityId); #### Entity[] GetEntities(int Mask) 从ECSWorld中获取*满足Mask筛选条件*的实体(们)。 var res = ECSWorld.GetEntities(ComponentA.Mask | ComponentB.Mask); //获取含有ComponentA和ComponentB组件的实体(们)。 #### T[] GetComponents() 从ECSWorld中获取T类组件的切片。 ComponentA[] res = ECSWorld.GetCompnents(); #### void ClearEntity() 将所有实体解除注册。 #### void AddSingletenComponent() 新建一个T类型的单例组件,*如果单例组件复例了,会抛出异常*。 #### T GetSingletenComponent() 获取一个T类型的单例组件 #### void RemoveSingletenComponent() 删除一个T类型的单例组件 #### void ClearSingletenComponents() 清空所有单例组件 #### T AddSystem() 在ECSWorld中注册一个T类型的系统,*如果系统复例了会抛出异常* #### T GetSystem() 获取ECSWorld中的T类型系统 #### void RemoveSystem() 解除ECSWorld中T类型的系统的注册 #### void ClearSystem() 解除所有系统的注册 #### void UpdateOnce() 轮询所有已注册的满足WillTick条件的System的Tick函数 #### int GetMaskOfType(Type t) 获取t类的Mask #### int GetMaskOfTypes(params Type[] t) 获取输入类型的Mask的按位或 ## ComponentBase 组件基类,注意组件的要求是除了初始化方法外无任何其他的方法 ### static filed #### public static int Mask 该类的Mask,如果不声明获取的时候会抛出异常 ### public filed #### public int EntityID { get; } 该组件挂载的实体在ECSWorld中的ID ### public funcs #### public virtual ComponentBase Init() 初始化用函数,如果不声明的话引用的时候会抛出异常 #### 组件派生的例子: class PositionComponent : ComponentBase { //public new static int Mask { get; } = MaskDistributer.DefaultContainer.GetMask(typeof(PositionComponent));//TODO:性能测试 private static readonly int _mask = MaskDistributer.DefaultContainer.GetMaskOfType(typeof(PositionComponent)); public new static int Mask { get { return _mask; } } public float x, y, z; public PositionComponent Init(int x, int y, int z) { this.x = x; this.y = y; this.z = z; return this; } } ## ISystem 系统接口,要求实现 void Tick();//轮询接口 bool WillTick();//触发条件接口 ## SystemBase 便于派生的系统类基类,注册到ECSWorld的所有系统要从该类派生,一样要实现Tick()和WillTikc()接口,否则会抛出异常。 ### bool WillTick() 检查是否进行轮询的接口函数,如果返回true那么在这一次的ECSWorld.UpdateOnce()中该系统的Tick()函数会被调用。 ### void Tick() 轮询的主函数,系统功能的实现位置。 #### 一个例子: public class ChangePositionSystem : SystemBase { public override void Tick() { var positions = ECSWorld.GetComponents(); int _n = positions.Length; for (int i = 0; i < _n; i++) { positions[i].x *= 9; } } public override bool WillTick() { return true; } }