This document is about: QUANTUM 2
SWITCH TO

スニペット

Bot SDKと使用ふぇきる便利なコードスニペットをご紹介します。

Compound Agent(複合エージェント)

同一のエンティティで稼働するAIエージェントコンポーネントとが複数あるほうが便利な場合があります。
例えば、エンティティを移動させることに特化したHFSMと、また別のHFSMがターゲット攻撃に特化していたようなケースです。
同一のエンティティにおいて様々な技術を混在させることもできます。一部をHFSMで構築し、ほかのブウbンをBTで構築することなどが可能です。

このようなステップをとる場合、エンティティに複数のメモリーストレージを提供しておくことも有用です。Bot SDKでは、AIBlackboardコンポーネントを使用することが一般的です(ただし、必須ではありません)。

複数のコンポーネントを一つのエンティティに追加してここでCompound Agent(複合エージェント)と呼ぶエンティティを作成する方法を示すコードスニペットをご紹介していきます。

複合コンポーネントを作成する

DSL(.qtnファイル)で、以下のコンポーネントを追加します。
コンポーネントに、意味を持つゲーム特有の名前をつけたり、汎用的な方法でリストに追加しても構いません。
このサンプルでは、エンティティのMoving(移動)のみを担うHFSMと、Attack(攻撃)のみを担うエンティティを使用しています。

C#

component CompoundAgents
{
    HFSMAgent MovementHFSMAgent;
    HFSMAgent AttackHFSMAgent;

    AIBlackboardComponent MovementBlackboard;
    AIBlackboardComponent AttackBlackboard;

    AssetRefAIBlackboardInitializer MovementBBInitializer;
    AssetRefAIBlackboardInitializer AttackBBInitializer;
}

AIContextを拡張する

AIContextの部分実装を作成しますここでのコンテキストは、「アップデートされたエンティティに関して、どのHSFMがアップデートされたのか?そのHSFMが使用しているのはどのBlackboardか?」などです。

C#

namespace Quantum
{
    public unsafe partial struct AIContext
    {
        public readonly HFSMAgent* HfsmAgent;
        public readonly AIBlackboardComponent* Blackboard;

        public AIContext(HFSMAgent* hfsmAgent, AIBlackboardComponent* blackboard)
        {
            this.HfsmAgent = hfsmAgent;
            this.Blackboard = blackboard;
        }
    }
}

Agents と Blackboardを初期化する

ISignalOnComponentAddedで例を出していますが、ユーザーの希望次第です。

C#

public void OnAdded(Frame frame, EntityRef entity, CompoundAgents* compoundAgents)
{
    // Initialise Agents
    HFSMRoot hfsmRoot = frame.FindAsset<HFSMRoot>(compoundAgents->MovementHFSMAgent.Data.Root.Id);
    HFSMManager.Init(frame, &compoundAgents->MovementHFSMAgent.Data, entity, hfsmRoot);

    hfsmRoot = frame.FindAsset<HFSMRoot>(compoundAgents->AttackHFSMAgent.Data.Root.Id);
    HFSMManager.Init(frame, &compoundAgents->AttackHFSMAgent.Data, entity, hfsmRoot);

    // Initialise Blackboards
    AIBlackboardInitializer initializer = frame.FindAsset<AIBlackboardInitializer>(compoundAgents->MovementBBInitializer.Id);
    AIBlackboardInitializer.InitializeBlackboard(frame, &compoundAgents->MovementBlackboard, initializer);

    initializer = frame.FindAsset<AIBlackboardInitializer>(compoundAgents->AttackBBInitializer.Id);
    AIBlackboardInitializer.InitializeBlackboard(frame, &compoundAgents->AttackBlackboard, initializer);
}

すべてのAgentをアップデートする

AIコンテキストを作成して、各HFSMとBlackboardで記入し、アップデートを実行します。:

C#

public override void Update(Frame frame, ref Filter filter)
{
    HFSMData* movementData = &filter.CompoundAgents->MovementHFSMAgent.Data;
    HFSMData* rotationData = &filter.CompoundAgents->RotationHFSMAgent.Data;
    HFSMData* attackData = &filter.CompoundAgents->AttackHFSMAgent.Data;

    AIContext aiContext = new AIContext(&filter.CompoundAgents->MovementHFSMAgent, &filter.CompoundAgents->MovementBlackboard);
    HFSMManager.Update(frame, frame.DeltaTime, movementData, filter.EntityRef, ref aiContext);

    aiContext = new AIContext(&filter.CompoundAgents->RotationHFSMAgent, &filter.CompoundAgents->RotationBlackboard);
    HFSMManager.Update(frame, frame.DeltaTime, rotationData, filter.EntityRef, ref aiContext);

    aiContext = new AIContext(&filter.CompoundAgents->AttackHFSMAgent, &filter.CompoundAgents->AttackBlackboard);
    HFSMManager.Update(frame, frame.DeltaTime, attackData, filter.EntityRef, ref aiContext);
}

AIContextオブジェクトからHFSM固有のブラックボードを取得する

こちらは、コンテキスト固有のブラックボードに記述するActionのスニペットです。どれがどれか判断することは不可知ですので、コードはデカップリングされます。どのブラックボードを使うべきか判断するために、Actionに多くのボイラープレートコードを追加する必要はありません。

C#

namespace Quantum
{
    [System.Serializable]
    public unsafe class WriteBlackboardCompound : AIAction
    {
        public int Value;

        public override void Update(Frame frame, EntityRef entity, ref AIContext aiContext)
        {
            aiContext.Blackboard->Set(frame, "TestInteger", Value);
        }
    }
}
Back to top