当前位置:   article > 正文

Unity ECS之Entitas学习笔记(一)

Unity ECS之Entitas学习笔记(一)

1.Entity的大致说明


Entity就是实体,它不包括数据和执行逻辑,只是一个id标识,但它可以添加组件以及移除组件来行成一个Group组。

1.1.Entity的添加


其中Entity实体的生成只能通过上下文来生成
contex.CreateEntity();
当生成实体后,可以根据实体来进行组件的添加和移除,但这里的移除并不是真正的移除,而是会添加到上下文的对象池

2.Entity对组件的操作说明

如何添加移除组件,当组件写出后,可以进行代码生成,代码生成会自动为实体生成一个partial类,这个类会根据组件的标签来确定名字。

2.1示例


比如我们创建了一个InterationExampleView组件继承了IComponent,它的标签是Game,那么生成代码就会生成一个内部类GameEntity,这个内部类只负责处理PositionComponent组件的操作,比如加这个组件或者替换这个组件这里只关注Add和Replace,我们发现它们的前三行代码都相同,大概意思就是先从一个类中拿到index,以及创建这个组件,并且给新的组件赋值,然后才是具体的添加或者代替的操作

  1.     public void AddInterationExampleView(UnityEngine.Transform newViewTrans) {
  2.         var index = GameComponentsLookup.InterationExampleView;
  3.         var component = (InterationExample.ViewComponent)CreateComponent(index, typeof(InterationExample.ViewComponent));
  4.         component.viewTrans = newViewTrans;
  5.         AddComponent(index, component);
  6.     }
  7.     public void ReplaceInterationExampleView(UnityEngine.Transform newViewTrans) {
  8.         var index = GameComponentsLookup.InterationExampleView;
  9.         var component = (InterationExample.ViewComponent)CreateComponent(index, typeof(InterationExample.ViewComponent));
  10.         component.viewTrans = newViewTrans;
  11.         ReplaceComponent(index, component);
  12.     }


两个重要属性,分别是得到实体的具体组件以及是否有这个组件,这两个属性一般用于反应式系统中的Filter和GetTrigger中来得到一个收集器以及筛选需要进入Execute方法的实体集合

  1.     public InterationExample.ViewComponent interationExampleView { get { return (InterationExample.ViewComponent)GetComponent(GameComponentsLookup.InterationExampleView); } }
  2.     public bool hasInterationExampleView { get { return HasComponent(GameComponentsLookup.InterationExampleView); } }

3.Component说明


Component是ECS中的数据重要的载体,也是System与Entity操作的对象。它只包含数据,当然这个数据可以是一个引用,也可以只是单纯的数据,甚至可以没有数据(这里即使没有数据,继承的接口也会给一个数据,一般用于标志变量)。

3.1 Component的基本形式


①首先可以选择给不给若干个标签,这个标签是自己定义的,不同的标签会对生成的代码的去向造成影响,其中有一个Unique定义全局唯一的组件数据,其中还有一种标签为[Event(EventTarget.Any/Self)]当有这个标签时,我们自动生成代码会生成一个接口,当这个组件数据改变时会调用实现接口的方法
②其次对数据也可以打上标签,比如[EntityIndex]标签,如果打上这个标签,则生成代码是会自动生成两个扩展方法,在其他任何类中,哪怕是继承了Mono的或者是Input中,都可以根据这两个方法来查找实体。其中一个方法可以为根据一个二维的向量来获取有这个实体的组件,可以是某个点或者其他的。还有一个是根据名字找。这两个方法返回的都是哈希表。

  1.     [Game,Event(EventTarget.Any)]
  2.     public class NameComponent : IComponent
  3.     {
  4.         [EntityIndex]
  5.         public string name;
  6.     }


该示例就是一个组件类的写法

3.2 Component组件的替换与添加

组件替换与添加离不开实体,这里可以在2.1看到,实体会操控这两个函数以实现添加或者移除组件,当数据更新时要调用.示例可以看4.1.2

4.System说明


System是实现逻辑的地方,在Entitas中可通过响应式系统来实现逻辑操作。

4.1 ReactiveSystem说明


它是响应式系统,通常我们自己写的某些System需要继承它,只有当满足某些条件时才会执行,它有三个抽象方法必须实现,分别是

  1. protected abstract ICollector<TEntity> GetTrigger(IContext<TEntity> context);
  2. protected abstract bool Filter(TEntity entity);
  3. protected abstract void Execute(List<TEntity> entities);


其中GetTrigger()返回一个收集器,这个收集器会返回所有上下文匹配的实体的集合,它会在系统初始化时调用
Filter()是筛选器,它进一步筛选符合条件的实体去执行Execute,这个一般都会用到自动生成代码的两个属性进行筛选
Execute()就是对所有符合条件的实体进行组件数据的更新的方法,也是逻辑核心执行的地方

4.2 示例

  1.     public class AddViewSystem : ReactiveSystem<GameEntity>
  2.     {
  3.     //父物体的Transform
  4.         private Transform parent;
  5.     //上下文
  6.         private Contexts contexts;
  7.         public AddViewSystem(Contexts contexts) :base(contexts.game)
  8.         {
  9.             parent = new GameObject("ViewParent").transform;
  10.             this.contexts = contexts;
  11.         }
  12.         protected override void Execute(List<GameEntity> entities)
  13.         {
  14.             foreach(GameEntity entity in entities)
  15.             {
  16.         //实例化一个物体
  17.                 GameObject go = new GameObject("View");
  18.         //设置父物体
  19.                 go.transform.SetParent(parent);
  20.         //将物体 与实体与上下文联系起来
  21.                 go.Link(entity, contexts.game);
  22.         //添加View组件,因为筛选器是筛选的没有这个组件的实体
  23.                 entity.AddInterationExampleView(go.transform);
  24.         //设置实体MoveComplete的数据
  25.                 entity.isInterationExampleMoveComplete = true;
  26.             }
  27.         }
  28.         protected override bool Filter(GameEntity entity)
  29.         {
  30.         //一般has。。。表示有无这个组件,is。。。表示是否是这个状态,它只是一个表示变量,当Component没有数据时自动生成
  31.                 return entity.hasInterationExampleSprite && !entity.hasInterationExampleView;
  32.         }
  33.         protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
  34.         {
  35.         //收集匹配的实体并且返回
  36.                 return context.CreateCollector(GameMatcher.InterationExampleSprite);
  37.         }
  38.     }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/112432
推荐阅读
相关标签
  

闽ICP备14008679号