This document is about: QUANTUM 2
SWITCH TO

Blackboard

はじめに

Blackboard は、Bot SDKに含まれているとても便利なツールです。
独自のカスタマイズされたデータを保持するために使用できるキー/値のセットです。
コンポーネントに保存されたカスタムデータを保持するのと同じような作用を持ちますが、主な違いはこれがDSLで物を作成したり再コンパイルする必要なくUnityのVisual Editorで作成されるためとても動的であるという点です。
エージェントごとに保持できるActionおよびDecisionの読み取り/書き込みメモリのようなものです。

Blackboardはデータアセットを使用して完全に定義され、Visual Editorのみを使用して作成されるため、設計者にとっても使いやすいです。
つまり、UnityプロジェクトでBlackboardを保存および整理することができます。

PS: Blackboardデータアセットは単なるメモリレイアウト定義であることを理解することが重要です。
同じメモリレイアウトを持つボット/エンティティが多数ある場合、それらはすべて同じBlackboardアセットを指すことができます。
これらのボットはそれぞれ、レイアウトに基づいて 独自のメモリ を持ちます。

シンプルな例

マップ上のいくつかのアイテムを集めるキャラクターがあるとします。
ActionとDecisionで特定のDecisionを下すために、キャラクターがすでに収集したアイテムの量を読む必要があります。
また、キャラクターがアイテムをもう一つ収集した際、アイテム数を増やす必要があります。
このために、整数型のItemsAmountという名前のエントリをBlackboardに作成し、ActionおよびDecisionコードで管理します。

すべてのエンティティにはランタイム時に作成される独自のblackboardメモリがあります。一つのエンティティがほかのエンティティのblackboardメモリを読み込むこともできるということです。blackboardメモリは1つだけでは なく、全てのエージェント間で共有されるものです。つまり、エージェントごとに一つ となります。

Visual EditorのBlackboard

Visual EditorにはすでにBlackboardのサブメニューが付属しています。
Blackboard Variablesという名前で、左側のパネルからアクセスできます。

Blackboard Visual Editor Empty

+ ボタンを押して、新しいBlackboard変数を作成することができます。
新しいエントリの作成・編集を行う際は、以下を定義します。

  • 変数のName。blackboardアセット上、内部でKeyとして使用され変数の値を取り出します;
  • 変数のType。ドロップダウンメニューから検索します;
  • HasDefaultチェックボックス。設定上この変数がデフォルト値に初期化されるかされないか通知するのに使用されます。;
  • 使用されるDefault値。
Blackboard Visual Editor Creating Entry

多くの型を持つ沢山のエントリを持つことができます。それらのすべてがデフォルト値を持つ必要はありません:

Blackboard Visual Editor Many Entries

現在Blackboardが対応しているタイプは以下の通りです。

  1. Boolean;

  2. Byte;

  3. Integer;

  4. FP;

  5. Vector2;

  6. Vector3;

  7. Entity Ref.

これで、プロジェクトをコンパイルするたびに、フォルダAssets/Resources/DB/CircuitExport/Blackboard_Assetsに2つの追加のデータアセットが自動的に作成されます。

  • コンパイル済みHFSMによって定義されたエントリをもつ Blackboard アセット。
  • コンパイル済みHFSMによって定義されたエントリとデフォルト値をもつ Blackboard Initializer アセット。

アセットはお互いに関連づいています。一つ目のアセットは単にレイアウトで、二つ目のアセットはblackboardが初期化される際に挿入する値を定義しています。

Blackboard Assets

これらはすでに情報の読み取り/書き込みに使用できます。

Blackboardノード

変数がある場合、グラフにドラッグ&ドロップしてノードを作成できます。これらのノードには常にKeyValueという、2つのアウトバウンドスロットがあります。

Blackboard Assets

KeyスロットはAIBlackboardValueKey種類のフィールドにリンクするため使用されます。このフィールドは、取得・設定する変数のキーを通知するときにハードコードされた文字列を置き換えるのに使用します。そしてもちろん、ハードコードされたキーを削除することで、コードはよりリライアブルになり、柔軟性も上がります。

ハードコードされたキーを使用している場合、またはBlackboardノードのキーを使用している場合それぞれのGet/Setメソッドの使用法について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);

この新しいフィールドが宣言されると、Visual Editorへ移動して、Blackboard Nodeの Keyスロットをつなげることができます。例:

Blackboard Assets

Keyスロットをこのように使用する他、Valueスロットをつなげて同じ種類のフィールドを定義することも可能です(Action/Decision上で整数フィールドにリンクされている整数のblackboard変数など)。左のパネルで定義されているDefault値はアセットにベイクする値となります。

Blackboard Assets

Blackboardおよびそのノードを使用するタイミング

いつでも好きな時に使用して、ランタイム中に変更する可能性のあるデータのプレエンティティを保管します。変わることのない値を定義する必要がある場合は、代わりにコンスタントパネルを使用してみてください。

Blackboard Quantumコード

Blackboardコンポーネントを初期化します

blackboardコンポーネントを初期化するのに大切なことは、Visual EditorでAIドキュメントをコンパイルした際に作成されたAIBlackboardInitializerへのリファレンスを保持することです。

それから、プロジェクトコードでそのリファレンスを用いてコンポーネントを初期化します。:

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を使用してBlackboardから読み取り・書き込みを行うことができるようになります。

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);

Blackboardコンポーネントの破棄

Blackboardコンポーネントを使用するエンティティを破棄する場合には、メモリリークを避けるため、コンポーネントを解放することが重要です。

Blackboardメモリを破棄するには、blackboardComponent->Free(frame);を使用します。


PS.: バージョン1.0 RC2以降のBotSDK には既にActions/Decisionsのサンプルが搭載されています。quantum_codeソリューションで、BotSDK/Samplesフォルダを開き、IncreaseBlackboardInt.csSetBlackboardInt.csHFSM.CheckBlackboardInt.csのファイルを確認してください。

Back to top