Index 索引
當我們想獲取所有擁有Position Component 的Entity的時候,我們會創(chuàng)建一個Group然后遍歷他器钟。但是,如果我們只想獲取某個Position上的Entity時逻族,我們要怎么做呢?我們可以遍歷所有有Position Component的Entity然后找到特定Position的Entity氮块,或者我們可以用Index。
為了創(chuàng)建一個索引诡宗,我們需要給Component增加以下屬性(注釋):
using Entitas;
using Entitas.CodeGeneration.Attributes;
[Game]
public sealed class PositionComponent : IComponent {
[EntityIndex]
public IntVector2 value;
}
這個EntityIndex
屬性會告訴我們的代碼生成器滔蝉,在Context上創(chuàng)建一個讓用戶能夠根據(jù)IntVector2
來獲取Entities的API。
這是MatchOne例子上從ProcessInputSystem
中提取出來的代碼片段:
foreach (var e in _contexts.game.GetEntitiesWithPosition(
new IntVector2(input.x, input.y)
).Where(e => e.isInteractive)) {
e.isDestroyed = true;
}
在這個片段中塔沃,我們向Context請求所有所有“input”位置上的Entities并且篩選出所有interactive的Entities蝠引。
在內(nèi)部,Index其實就是一個group觀察者蛀柴。他在context初始化的時候創(chuàng)建螃概,從一開始就訂閱了group變化的事件。當我們開始創(chuàng)建entites并且在上面增加components時鸽疾,他們就會進入groups以及index會被通知到entity被增加了對應(yīng)的component吊洼。我們可以使用component的值來做哈希表中的key,entity本身作為value制肮。這樣我們就建立起了一個index冒窍。當我們replace或者 remove component的時候,這個index也會被通知到豺鼻,它會獲取到之前的component综液。所以當我們在entity中replace成其他component的時候,index會從哈希表中移除舊component的key儒飒,并且接受到一個帶有新的value的added event谬莹。
在Entitas-CSharp中,我們有兩種內(nèi)置的index约素。EntityIndex
以及PrimaryEntityIndex
届良。EntityIndex
是依靠哈希表來存儲一組entity來作為值,這就意味著你可以有多個entity在同一個位置上圣猎。PrimaryEntityIndex
確保每一個key都是只與一個entity相關(guān)聯(lián)邓深。當你擁有Id
Component并且想用Id
Component來查找Entity的時候营袜,就非常方便了。但你需要存儲一個Entity的引用到另一個Entity中時梨熙,我們也推薦你使用這種方法(更多關(guān)于這方面的會在ingredience 的章節(jié)中說到)爪模。
就像上一段中說到的欠啤,Entitas-CSharp僅僅實現(xiàn)了兩種簡單的Entity Indexing的策略。你可能會需要更多更復(fù)雜的Index來讓你獲取某個范圍內(nèi)的enitity或是擁有一個更為復(fù)雜的Index key屋灌。這種情況下呢洁段,你可以看一看AbstractEntityIndex
類。將這本書提供給你的知識融會貫通共郭,你應(yīng)該會非常輕易地理解Index的實現(xiàn)并且寫出自己自定義的Index祠丝。