(转)我所理解的Entitas——Matcher Collector(五)
图中可以看到一个Context具有多个Entity,每个Entity可能会被N个Group所关心。
Group
一个Context中可能会同时存在很多个Entity,但是有些时候我们只需要处理某些Entity,那么我们可以通过Group来快速访问,每个Context内部维护一个Group对象集合,调用GetGroup()方法可以拿到Group,相同得Matcher参数拿到得是相同得Group对象。
Group是实时更新的一个具有相同筛选条件的Entity的组合,它会自动添加具有筛选条件的Entity,并删除失去筛选条件的Entity,以提高下一次的访问速度。
public IGroup<TEntity> GetGroup(IMatcher<TEntity> matcher) { if (!_groups.TryGetValue(matcher, out IGroup<TEntity> group)) { group = new Group<TEntity>(matcher); TEntity[] entities = GetEntities(); for (int i = 0; i < entities.Length; i++) { group.HandleEntitySilently(entities[i]); } _groups.Add(matcher, group); for (int j = 0; j < matcher.indices.Length; j++) { int num = matcher.indices[j]; if (_groupsForIndex[num] == null) { _groupsForIndex[num] = new List<IGroup<TEntity>>(); } _groupsForIndex[num].Add(group); } if (this.OnGroupCreated != null) { this.OnGroupCreated(this, group); } } return group; }
可以通过GetEntities()拿到Group中得所有Entity。通过ContainsEntity()接口判断Group中是否包含某个Entity。
Gorup提供了OnEntityAdded,OnEntityRemoved,OnEntityUpdated事件委托监听Group内部得Entity变化。
gameContext.GetGroup(GameMatcher.Position).OnEntityAdded += (group, entity, index, component) => { // Do something };
Matcher
Matcher是Group的筛选条件,筛选条件就是Context中所拥有的Component。
例:
我们有MoveComponent和AttackComponent两个组件存在Game Context中。则我们可以有一下几种查询方式:
//查找所有有MoveComponent的Entity var moveEntitys = contexts.game.GetGroup(GameMatcher.Move); //查找所有有AttackComponent的Entity var attackEntitys = contexts.game.GetGroup(GameMatcher.Attack); //查找所有有MoveComponent和AttackComponent的Entity int[] allMatcher = { GameComponentsLookup.Move,GameComponentsLookup.Attack }; var AllEntitys = contexts.game.GetGroup(GameMatcher.AllOf(allMatcher)); //查找所有有MoveComponent或AttackComponent的Entity int[] anyMatcher = { GameComponentsLookup.Move, GameComponentsLookup.Attack }; var AnyEntitys = contexts.game.GetGroup(GameMatcher.AnyOf(anyMatcher));
Collector
通过Group和Matcher已经可以拿到所有符合条件的Entity,例如所有具有MoveComponent的Entity。也说过了Group会实时更新,但是如果我们需要知道Group中当前哪些Entity是新加进来的。则可以通过Collector来找到。
例:
//查找所有有MoveComponent的Entity var moveEntitys = contexts.game.GetGroup(GameMatcher.Move); //找到哪些Entity是刚刚获得了MoveComponent然后被添加到Gorup中的 var collect = moveEntitys.CreateCollector<GameEntity>(GroupEvent.Added);
GroupEvent
+ Added 添加到Gorup中的 + Removed 从Group中移除的 + AddedOrRemoved 所有变化的(包含添加的和移除的)
总结:
前面说过了空军指挥部(System_3)可以指挥拥有开飞机(Component_3)技能的士兵(Entity)飞往指定的地方完成任务A,那么就需要通过Group拿到所有能开飞机(Component_3)的士兵(Entity)。
但是可能所有能开飞机(Component_3)的士兵(Entity)都在执行任务B,这时候可以加班训练新的士兵(Entity)让其拥有开飞机(Component_3)的技能,然后通过Collector找到这些刚刚学会开飞机(Component_3)技能又不在出任务的士兵(Entity)去完成任务A。
原文地址:https://blog.csdn.net/u010020342/article/details/109898655?spm=1001.2014.3001.5502