ECS的簡單入門(二):Entity

介紹完ECS的大致理念之後,我們接着單獨來了解下Entity,Component和System的概念以及使用,首先我們先從Entity開始入手。

 

Entity概念

我們來看下Entity的組成,代碼如下,只有Index和Version兩個字段。

public struct Entity
{
    /// <summary>
    /// The ID of an entity.
    /// </summary>
    public int Index;
    public int Version;
}

我們可以理解爲Entity就是遊戲中不同的物體,其中只有一個ID,也就是Index用來進行區分。Entity中不存在任何數據和行爲,這些交給了Component和System去辦了。

在每個World中,會有一個EntityManager來管理該World下所有的Entity,EntityManager利用NativeArray來管理Entities並且紀錄了每個Entity和Component的關係。

World

我們可以將其理解成一種Manager,每一個World都擁有一個EntityManager和一系列的System,我們可以自由的創建World:

World newWorld = new World("NewWorld");

ECS中會有一個默認的World(DefaultWorld),可以通過 World.DefaultGameObjectInjectionWorld 來獲取它。系統自帶的System和我們自定義的System默認都會被添加進這個World。

 

創建Entity

創建一個Entity

前面我們說到Entity是由EntityManager來管理的,而EntityManager又存放與World之中,因此要創建Entity,我們先要獲得EntityManager,然後就可以利用其CreateEntity方法來創建我們的Entity了。

EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity entity = mEntityManager.CreateEntity();

若要爲Entity添加組件,也需要使用EntityManager來完成,例如添加一個用於存放座標信息的Translation Component並且賦值:

entityManager.AddComponentData(entity, new Translation(){Value = new float3(0, 0, 0)});

若要刪除Entity上的Component,自然是要用RemoveComponent方法了:

entityManager.RemoveComponent<Translation>(entity);

除此之外,我們也可以在創建的時候就指定好需要添加的組件,然後再利用 SetComponentData 賦值,例如:

Entity entity = entityManager.CreateEntity(typeof(Translation), typeof(OtherComponent), ...);
entityManager.SetComponentData(entity, new Translation(){Value = new float3(0, 0, 0)});

前面我們提到Component的不同組合被稱爲Archetype,因此我們也可實現聲明好Archetype,然後用其創建Entity,這樣生成的Entity就會帶有Archetype所代表的所有Component(其實和上面那種方法是等價的)。

EntityArchetype entityArchetype = entityManager.CreateArchetype(typeof(Translation), typeof(LocalToWorld), typeof(RenderMesh));
Entity entity = entityManager.CreateEntity(entityArchetype);
entityManager.SetComponentData(entity, new Translation(){Value = new float3(0, 0, 0)});

對於已存在的Entity,我們可以使用EntityManager.Instantiate方法來進行copy

Entity entity2 = entityManager.Instantiate(entity);

 

創建多個Entity

CreateEntity不僅可以創建一個Entity,也可以同時創建多個Entity,前提是要事先聲明好EntityArchetype,例如

NativeArray<Entity> entityArray = new NativeArray<Entity>(10, Allocator.Temp);
entityManager.CreateEntity(entityArchetype, entityArray);
entityArray.Dispose();

等價於

entityManager.CreateEntity(entityArchetype, 10, Allocator.Temp).Dispose();;

對於已存在的Entities我們可以進行整體copy,Entities中的數據都會被copy到新的Entities中。

NativeArray<Entity> copyEntityArray = new NativeArray<Entity>(10, Allocator.Temp);
entityManager.Instantiate(entityArray, copyEntityArray);
copyEntityArray.Dispose();

Instantiate也可將單個Entity進行多份copy

entityManager.Instantiate(entity, 10, Allocator.Temp);

 

銷燬Entity

entityManager.DestroyEntity(entity);

 

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