(轉)我所理解的Entitas——Component(三)

這章我們將介紹ECS的三大基本概念中的Component。

Component 組件
組件是ECS框架中基礎的數據結構單元。每個Compoent只有數據,不包含任何處理數據的方法。在內存中相同類型的組件是緊密排列的,這樣在System中遍歷擁有相同組件的實體時大大的提高內存命中率。這也是ECS框架用來做很多大型項目或者多物體的項目的原因之一。

Entitas中所有組件全部繼承自IComponent接口。同時Entitas提供了各種特殊標籤屬性,在生成代碼的時候爲我們提供特殊功能。例如 [Context] 指定將該組件添加一個或者多個Context中。關於屬性標籤可以查看這裏(Attributes)。

我們定義的組件在生成的代碼的時候會自動生成所屬的Context文件夾下的Components文件夾中。

 

一個Context可以包含多個組件,自動生成時實際上個是通過partial(不完全類)的方式爲當前Context下的Entity提供相關接口。如果一個組件被添加到多個Context中,則每個Context下都會有該組件。

前面說過組件內部只有數據,但是我們創建組件的時候也可以不包含數據。如果包含任意類型的數據,生成代碼時會自動幫我們定義 has,Add,Replace,Remove四個接口,如果沒有任何數據則只會給我們提供一個bool的屬性。
例 :

我們定義如下兩個接口:

//組件一 不包含數據
public class TestFlagComponent : IComponent
{

}

// 組件二 包含數據
public class TestValueComponent : IComponent
{
    public int value;
}
  • 組件一自動生成代碼
public partial class InputEntity {

        static readonly TestFlagComponent testFlagComponent = new TestFlagComponent();

        public bool isTestFlag {
            get { return HasComponent(InputComponentsLookup.TestFlag); }
            set {
                if (value != isTestFlag) {
                    var index = InputComponentsLookup.TestFlag;
                    if (value) {
                        var componentPool = GetComponentPool(index);
                        var component = componentPool.Count > 0
                                ? componentPool.Pop()
                                : testFlagComponent;

                        AddComponent(index, component);
                    } else {
                        RemoveComponent(index);
                    }
                }
            }
        }
    }

 

  • 組件二自動生成代碼
public partial class InputEntity {

        public TestValueComponent testValue { get { return (TestValueComponent)GetComponent(InputComponentsLookup.TestValue); } }
        public bool hasTestValue { get { return HasComponent(InputComponentsLookup.TestValue); } }

        public void AddTestValue(int newValue) {
            var index = InputComponentsLookup.TestValue;
            var component = (TestValueComponent)CreateComponent(index, typeof(TestValueComponent));
            component.value = newValue;
            AddComponent(index, component);
        }

        public void ReplaceTestValue(int newValue) {
            var index = InputComponentsLookup.TestValue;
            var component = (TestValueComponent)CreateComponent(index, typeof(TestValueComponent));
            component.value = newValue;
            ReplaceComponent(index, component);
        }

        public void RemoveTestValue() {
            RemoveComponent(InputComponentsLookup.TestValue);
        }
    }

添加組件
一個Entity在被調用CreateEntity()方法創建出來時沒有任何組件信息,我們需要在合適的時機增加,刪除或者修改組件來改變Entity的行爲。

對於沒有數據的組件我們調用bool型的屬性來添加或者移除該組件
true 添加組件
false 移除移除
對於有數據的組組件
Add 添加組件
Replace 替換組件
Remove 移除移除
總結:
上一章說了Contexts,Context和Entity的關係。
Component可以理解爲技能,例如 開坦克(Component_1),開潛艇(Component_2), 開飛機(Component_3),。那麼一個士兵(Entity)要有開飛機(Component_3)的技能那麼首先他得是空軍(context_3)。當前不排除一個陸軍(context_1)的士兵即會開坦克(Component_1)也會開飛機(Component_3)(Component同時被添加到兩個Context中)

原文地址:https://blog.csdn.net/u010020342/article/details/109898611?spm=1001.2014.3001.5502

 

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