Blackboard
概述
黑板 是機器人SDK含有的另一個非常有用的工具。
它是一個索引鍵/值的集,您可以使用它來自訂您自己的自訂資料。它的工作方式非常像儲存在元件上的自訂資料,但是主要的不同點在於它非常動態,可以在Unity的視覺編輯器上建立它,而不需要在DSL上建立或重新編譯東西。
它像是一個您可以針對各個代理而有的,針對動作及決策的讀取/寫入記憶體。
黑板對於設計師來說也是友善的,因為它完全使用資料資產來定義,並且可以完全只使用視覺編輯器來建立。
所以您可以在您的Unity專案上儲存及組織您的黑板。
附註: 一個重要注意事項是,黑板資料資產只是記憶體 配置 定義。
如果您有許多應該有相同記憶體配置的機器人/實體,那麼所有這些機器人/實體都可以指向相同的黑板資產。
之後這些各個機器人將有基於定義的配置的,在運行階段時建立的其自己的記憶體。
一個非常簡單的示例
所以,如果您有一個角色,其收集地圖上的一些物件。
在您的動作及決策上,您可能希望讀取角色已經收集的物件的數量,以做成一個特定的決策。
同時,如果角色收集再多一個物件,物件計數應該增加。
為了做到這點,您可以在您的黑板上有一個輸入項目,名為ItemsAmount
,為整數類型,並且在您的動作及決策程式碼上管理它。
每個實體都有在運行階段時建立的,其自己的黑板記憶體,這意味著一個實體甚至可以讀取其他實體黑板記憶體。所以黑板記憶體 不是 只是在所有代理之間共享的一個——它是 每個代理都有一個。
在視覺編輯器上的黑板
視覺編輯器已經針對黑板而附有一個子選單。
它名為黑板變數,並且可以在左側面板上存取它:
按下 + 按鈕,以建立新的黑板變數。
當建立/編輯一個新的輸入項目時,您需要定義:
- 變數的
Name
,其在內部做為一個黑板資產上的索引鍵,以擷取某些變數的值; - 變數的
Type
,您可以從下拉式選單中選擇它; HasDefault
勾選框,用於告知這個變數是否在設定時將被初始化為一個預設值;- 將使用的
Default
值。
您可以有許多類型的許多個輸入項目,並且不強制總是定義預設值:
目前由黑板支援的類型有:
布林值;
位元組;
整數;
FP;
向量2;
向量3;
實體參照。
現在,不論您何時編譯您的專案,將在Assets/Resources/DB/CircuitExport/Blackboard_Assets
資料夾上自動建立兩個額外的資料資產:
- 一個 黑板 資產,其輸入項目由已編譯的HFSM所定義;
- 以及一個 黑板初始設定式 資產,其輸入項目及預設值也是由已編譯的HFSM所定義。
一個資產與其他相關連。第一個只定義配置,而第二個定義初始化黑板時,將插入的值。
黑板節點
有了這些變數,您可以拖放它們到圖表之中,以建立黑板節點。這些節點總是有兩個輸出槽:Key
以及Value
。
Key
槽用於被連接到AIBlackboardValueKey
類型的欄位,當告知變數的索引鍵以取得/設定時,其可用於替換已硬式編碼的字串。並且,理所當然地,透過移除已硬式編碼的索引鍵,程式碼將變得更有彈性且更可靠。
讓我們分析一下,從Quantum程式碼的角度,應該如何使用取得/設定方法,取決於您是否正在使用一個已硬式編碼的索引鍵,或是使用來自一個黑板節點的索引鍵:
C#
// -- Using hardcoded keys: --
var bbComponent = f.Unsafe.GetPointer<AIBlackboardComponent>(entityRef);
// To read
var value = bbComponent->GetInteger(frame, "someKey");
// To write
bbComponent->Set(frame, "someKey", value);
// -- Using keys from Blackboard nodes: --
public AIBlackboardValueKey PickupsKey;
// To read
var value = bbComponent->GetInteger(frame, PickupsKey.Key);
// To write
bbComponent->Set(frame, PickupsKey.Key, value);
宣告這個新的欄位之後,您可以前往視覺編輯器並且連接它到任何黑板節點的Key
槽到它。舉例而言:
除了如此使用Key
槽,也可以連接Value
槽,以定義同樣該類型的欄位(舉例而言,一個整數黑板變數被連接到某些動作/決策上的整數欄位)。在左側面板上定義的Default
值,是將被內嵌到資產之中的值。
當使用黑板及其節點時
在您希望針對各個實體,來儲存某些在運行階段時可以改變的資料時,都可以使用它。如果您希望定義永不改變的值,請考慮改為使用常數面板。
黑板Quantum程式碼
初始化黑板元件
對於初始化黑板元件而言的一個重要部分是,有一個參照到AIBlackboardInitializer
資產,該資產在您在視覺編輯器上編譯您的AI文件時建立。
然後,在您的專案的程式碼上,使用這個以初始化元件:
C#
// -- Blackboard setup
// First, create the blackboard component (or have it created on the Entity Prototype)
var blackboardComponent = new AIBlackboardComponent();
// Find the Blackboard Initializer asset
var bbInitializerAsset = f.FindAsset<AIBlackboardInitializer>(runtimeConfig.BlackboardInitializer.Id);
// Call the static initialization method passing the blackboard component and the asset
AIBlackboardInitializer.InitializeBlackboard(f, &blackboardComponent, bbInitializerAsset);
// Set the blackboard into to the entity
f.Set(littleGuyEntity, blackboardComponent);
這樣就完成了。當您已經完成所有參照及初始化,您已經準備好使用黑板的API,從黑板來讀取/寫入
C#
// There is one method for each specific blackboard type (int, byte, FP, boolean, FP vectors and entityRef)
blackboardComponent->GetInteger(frame, key);
// For the setter method, there are different overrides depending on the type of data passed as the value
blackboardComponent->Set(frame, key, value);
附註: 從1.0 RC2及之後的版本的機器人SDK,已經附有一些範例動作/決策,其讀取/寫入黑板。
在您的quantum_code
解決方案上,您可以前往BotSDK/Samples
資料夾,並且檢查IncreaseBlackboardInt.cs
、SetBlackboardInt.cs
及HFSM.CheckBlackboardInt.cs
檔案