#unity/日常积累 Attributes Entitas提供了各种属性在生成代码时提供特殊功能。 代码生成器支持以下与类,接口和结构一起使用的属性: [Context] 将组件添加到指定的Context,如果没有指定则会添加到默认Context中(Jenny 设置面板中定义的第一个Context)。 例: [Game] public class ViewComponent : IComponent { public GameObject gameObject; } 将View组件添加到Game Context中,生成代码后会在Generated/Game/Components文件夹下生成GameViewComponent类。 允许同时指定多个Context名称。 如果用于Class或者Struct上首先会在Generated/Components生成 {classname}Component的组件,然后同上 例: [Game] public class ContextView { public GameObject gameObject; } [Game] public struct ContextData { public float value; } [Unique] 将组件指定为单例模式,则每个Context中只存在唯一实例。 例: [Unique] public class UniqueTestComponent : IComponent { public int value; } 而单例组件的调用方式和其他组件也有所不同: Contexts _contexts = Contexts.sharedInstance; if (!_contexts.game.hasUniqueTest) { _contexts.game.SetUniqueTest(1); } Debug.Log(_contexts.game.uniqueTest.value); [FlagPrefix] 只对标记组件有效(没有数据的组件)。对标记组件指定自定义前缀。 例: [Game] [FlagPrefix("Custom")] public class FlagComponent : IComponent { } [Game] public class FlagTowComponent : IComponent { } 生成带之后Entity访问两种组件的方式: Contexts _contexts = Contexts.sharedInstance; var entity = _contexts.game.CreateEntity(); //指定前缀 entity.customFlag = true; //没有指定前缀则用默认前缀is entity.isFlagTow = true; [PrimaryEntityIndex] 在Context中添加索引器功能,可以用于快速查找Entity。注意同一Context下每个Entity的值不能相同。 例: [Game] public class PrimaryEntityIndexTestComponent : IComponent { [PrimaryEntityIndex] public string index; } _contexts.game.CreateEntity().AddPrimaryEntityIndexTest("a"); _contexts.game.CreateEntity().AddPrimaryEntityIndexTest("b"); var entity2 = _contexts.game.GetEntityWithPrimaryEntityIndexTest("a"); [EntityIndex] 这个属性的功能和[PrimaryEntityIndex]类似,区别在于[PrimaryEntityIndex]查找的是指定的值的唯一Entity,而[EntityIndex]是查找具有指定值的多个Entity,也就是多个Entity的[EntityIndex]的值可以是相同的。 [Game] public class EntityIndexComponent : IComponent { [EntityIndex] public string name; } _contexts.game.CreateEntity().AddEntityIndex("c"); _contexts.game.CreateEntity().AddEntityIndex("c"); _contexts.game.GetEntitiesWithEntityIndex("c"); [CustomComponentName] 为组件自定义名称且定义几个名称则生成几个具有相同数据但名称不同的组件。 例: [Game, ComponentName("Speed", "Position")] public class FloatVector { public float x; public float y; } 在Game Context下会生成GamePositionComponent组件和GameSpeedComponent组件,且两个组件都具有x,y两个值。 [DontGenerate] 生成代码时将跳过所有具有[DontGenerate]属性的组件。 例:我们之前需要有移动的功能所以定义了一个MoveComponent,并生成了代码,之后我们又不需要这个功能了所以想将这个组件移除 [DontGenerate(false)] public class CustomNameComponent { public int value; } 再只需加上[DontGenerate]然后重新生成,则Entitas会移除所有与MoveComponent相关的代码。 [Event] 为组件生成数据改变的事件。 例:我们需要监听某个Entity的位置变化 [Game, Event(EventTarget.Self)] public class PositionComponent : IComponent { public float x; public float y; } public class GameView: Monobehaviour, IPositionListener { // 注册事件监听 public void RegisterListeners(Contexts contexts, GameEntity entity) { entity.AddGamePositionListener(this); } // 事件回调响应函数 public void OnPosition(GameEntity entity, float x, float y) { transform.position = new Vector2(x,y); } } public class GameController : MonoBehaviour { private static Systems CreateSystems(Contexts contexts) { return new Feature("Systems") .Add(new GameEventSystems(contexts)); } } } 当Entity更改的位置时,生成的GameEventSystems将调用OnPosition(entity, x, y)的事件监听的回调。 参数: EventTarget Any 任何Entity的Position发生变化都会调用OnPosition()。OnPosition()回调中第一个参数就是发生位置变化的Entity。 Self 仅自身的Position发生变化时才会调用OnPosition()。 EventType Added 生成IPositionListener。 Removed 生成IPositionRemovedListener,当组件被移除时调用。 priority 生成的事件执行顺序,同一个Context中存在多个事件时值越小优先级越高。 [Cleanup] 这个是只对AssetStore版本生效,我使用的是Github版本,所以没办法测试,一下是官方文档翻译 当前有两种选择: CleanupMode.DestroyEntity 将生成一个系统,该系统将销毁所有具有此组件的实体。 CleanupMode.RemoveComponent 将生成一个系统,该系统将从具有此组件的所有实体中删除此组件。 例: [Cleanup(CleanupMode.DestroyEntity)] public sealed class DestroyedComponent : IComponent { }