赞
踩
Entity就是实体,它不包括数据和执行逻辑,只是一个id标识,但它可以添加组件以及移除组件来行成一个Group组。
其中Entity实体的生成只能通过上下文来生成
contex.CreateEntity();
当生成实体后,可以根据实体来进行组件的添加和移除,但这里的移除并不是真正的移除,而是会添加到上下文的对象池中
如何添加移除组件,当组件写出后,可以进行代码生成,代码生成会自动为实体生成一个partial类,这个类会根据组件的标签来确定名字。
比如我们创建了一个InterationExampleView组件继承了IComponent,它的标签是Game,那么生成代码就会生成一个内部类GameEntity,这个内部类只负责处理PositionComponent组件的操作,比如加这个组件或者替换这个组件这里只关注Add和Replace,我们发现它们的前三行代码都相同,大概意思就是先从一个类中拿到index,以及创建这个组件,并且给新的组件赋值,然后才是具体的添加或者代替的操作
- public void AddInterationExampleView(UnityEngine.Transform newViewTrans) {
- var index = GameComponentsLookup.InterationExampleView;
- var component = (InterationExample.ViewComponent)CreateComponent(index, typeof(InterationExample.ViewComponent));
- component.viewTrans = newViewTrans;
- AddComponent(index, component);
- }
-
- public void ReplaceInterationExampleView(UnityEngine.Transform newViewTrans) {
- var index = GameComponentsLookup.InterationExampleView;
- var component = (InterationExample.ViewComponent)CreateComponent(index, typeof(InterationExample.ViewComponent));
- component.viewTrans = newViewTrans;
- ReplaceComponent(index, component);
- }
两个重要属性,分别是得到实体的具体组件以及是否有这个组件,这两个属性一般用于反应式系统中的Filter和GetTrigger中来得到一个收集器以及筛选需要进入Execute方法的实体集合
- public InterationExample.ViewComponent interationExampleView { get { return (InterationExample.ViewComponent)GetComponent(GameComponentsLookup.InterationExampleView); } }
- public bool hasInterationExampleView { get { return HasComponent(GameComponentsLookup.InterationExampleView); } }
Component是ECS中的数据重要的载体,也是System与Entity操作的对象。它只包含数据,当然这个数据可以是一个引用,也可以只是单纯的数据,甚至可以没有数据(这里即使没有数据,继承的接口也会给一个数据,一般用于标志变量)。
①首先可以选择给不给若干个标签,这个标签是自己定义的,不同的标签会对生成的代码的去向造成影响,其中有一个Unique定义全局唯一的组件数据,其中还有一种标签为[Event(EventTarget.Any/Self)]当有这个标签时,我们自动生成代码会生成一个接口,当这个组件数据改变时会调用实现接口的方法
②其次对数据也可以打上标签,比如[EntityIndex]标签,如果打上这个标签,则生成代码是会自动生成两个扩展方法,在其他任何类中,哪怕是继承了Mono的或者是Input中,都可以根据这两个方法来查找实体。其中一个方法可以为根据一个二维的向量来获取有这个实体的组件,可以是某个点或者其他的。还有一个是根据名字找。这两个方法返回的都是哈希表。
- [Game,Event(EventTarget.Any)]
- public class NameComponent : IComponent
- {
- [EntityIndex]
- public string name;
- }
该示例就是一个组件类的写法
组件替换与添加离不开实体,这里可以在2.1看到,实体会操控这两个函数以实现添加或者移除组件,当数据更新时要调用.示例可以看4.1.2
System是实现逻辑的地方,在Entitas中可通过响应式系统来实现逻辑操作。
它是响应式系统,通常我们自己写的某些System需要继承它,只有当满足某些条件时才会执行,它有三个抽象方法必须实现,分别是
- protected abstract ICollector<TEntity> GetTrigger(IContext<TEntity> context);
- protected abstract bool Filter(TEntity entity);
- protected abstract void Execute(List<TEntity> entities);
其中GetTrigger()返回一个收集器,这个收集器会返回所有上下文匹配的实体的集合,它会在系统初始化时调用
Filter()是筛选器,它进一步筛选符合条件的实体去执行Execute,这个一般都会用到自动生成代码的两个属性进行筛选
Execute()就是对所有符合条件的实体进行组件数据的更新的方法,也是逻辑核心执行的地方
- public class AddViewSystem : ReactiveSystem<GameEntity>
- {
- //父物体的Transform
- private Transform parent;
- //上下文
- private Contexts contexts;
- public AddViewSystem(Contexts contexts) :base(contexts.game)
- {
- parent = new GameObject("ViewParent").transform;
- this.contexts = contexts;
- }
- protected override void Execute(List<GameEntity> entities)
- {
- foreach(GameEntity entity in entities)
- {
- //实例化一个物体
- GameObject go = new GameObject("View");
- //设置父物体
- go.transform.SetParent(parent);
- //将物体 与实体与上下文联系起来
- go.Link(entity, contexts.game);
- //添加View组件,因为筛选器是筛选的没有这个组件的实体
- entity.AddInterationExampleView(go.transform);
- //设置实体MoveComplete的数据
- entity.isInterationExampleMoveComplete = true;
- }
- }
-
- protected override bool Filter(GameEntity entity)
- {
- //一般has。。。表示有无这个组件,is。。。表示是否是这个状态,它只是一个表示变量,当Component没有数据时自动生成
- return entity.hasInterationExampleSprite && !entity.hasInterationExampleView;
- }
-
- protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
- {
- //收集匹配的实体并且返回
- return context.CreateCollector(GameMatcher.InterationExampleSprite);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。