這章我們將介紹ECS的三大基本概念種的Entity,同時Entity又和Context息息相關
Entity 實體
實體作爲ECS的三大基本概念之一,實體作爲組件的載體,本身並無實際意義,最核心的數據便是唯一ID,和Untiy的GameObject類似。在遊戲世界中可以被創建,被銷燬,可以添加組件,刪除組件。
實體初始化
Entitas中的實體只能由Context的CreateEntity()方法創建。可以大概看下源碼:
//判斷對象池是否有空閒對象 if (_reusableEntities.Count > 0) { entity = _reusableEntities.Pop(); //如果有,則拿出來,同時賦予新的ID entity.Reactivate(_creationIndex++); } else { //如果沒有,則創建,並且初始化 entity = _entityFactory(); entity.Initialize(_creationIndex++, _totalComponents, _componentPools,_contextInfo, _aercFactory(entity)); }
實體的銷燬
實體銷燬是調用Destroy()方法,但是這個方法並不是真正執行銷燬邏輯,Context內部提供了用來管理Entity的對象池,調用Destroy()方法時只是將實體身上的組件,委託事件等移除然後放入對象池等待下次使用:
public void Destroy() { if (!_isEnabled) { throw new EntityIsNotEnabledException("Cannot destroy " + this + "!"); } if (OnDestroyEntity != null) { OnDestroyEntity(this); } } public void InternalDestroy() { _isEnabled = false; RemoveAllComponents(); OnComponentAdded = null; OnComponentReplaced = null; OnComponentRemoved = null; OnDestroyEntity = null; }
Context 上下文
Context是Entity的上下文環境,用來管理當前環境下的所有Entity和Group的創建和回收。可以同時存在多個Context,Entitas默認會生成兩個Context,分別是Game,Input。可以在Jenny的設置面板修改Context。
注意:設置面板中的第一個Context將會被作爲默認的,會對之後生成組件產生影響,之後詳細講解。
生成的Context代碼存放在Generated文件夾下。
在生成Context時同時會生成Lookup類和一個Matcher類
- Lookup 用來管理當前Context的所有組件組件信息。
public static class InputComponentsLookup { public const int MyNameSpaceTestComponent = 0; public const int TestTwo = 1; public const int TotalComponents = 2; public static readonly string[] componentNames = { "MyNameSpaceTestComponent", "TestTwo" }; public static readonly System.Type[] componentTypes = { typeof(MyNameSpace.TestComponentComponent), typeof(TestTwoComponent) }; }
- Matcher 用來定義當前Context中的實體的篩選條件
public sealed partial class InputMatcher { public static Entitas.IAllOfMatcher<InputEntity> AllOf(params int[] indices) { return Entitas.Matcher<InputEntity>.AllOf(indices); } public static Entitas.IAllOfMatcher<InputEntity> AllOf(params Entitas.IMatcher<InputEntity>[] matchers) { return Entitas.Matcher<InputEntity>.AllOf(matchers); } public static Entitas.IAnyOfMatcher<InputEntity> AnyOf(params int[] indices) { return Entitas.Matcher<InputEntity>.AnyOf(indices); } public static Entitas.IAnyOfMatcher<InputEntity> AnyOf(params Entitas.IMatcher<InputEntity>[] matchers) { return Entitas.Matcher<InputEntity>.AnyOf(matchers); } }
同時存在的多個Context每個之間互不影響。所有的Context由Contexts管理。
Contexts
Contexts是個單例。通過Contexts.sharedInstance訪問,內部持有所有Context的引用。是由Entitas代碼生成器生成,無需手動實現也不能夠手動實現。
public partial class Contexts : Entitas.IContexts { public static Contexts sharedInstance { get { if (_sharedInstance == null) { _sharedInstance = new Contexts(); } return _sharedInstance; } set { _sharedInstance = value; } } static Contexts _sharedInstance; public GameContext game { get; set; } public InputContext input { get; set; } public Entitas.IContext[] allContexts { get { return new Entitas.IContext [] { game, input }; } } public Contexts() { game = new GameContext(); input = new InputContext(); } }
總結:
遊戲世界中的Contexts可以理解爲一個軍區司令。
軍區司令管理着多個軍種:陸軍(context_1),海軍(context_2),空軍(context_3)。
每個軍種又管這着具體的每爲士兵(Entity)。
原文地址:https://blog.csdn.net/u010020342/article/details/109898547?spm=1001.2014.3001.5502