(轉)我所理解的Entitas——Entity Context(二)

這章我們將介紹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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章