ゴドー動作ツリー
ネイティブ Godot ノードに基づき、組み込みのシーン ツリー エディタを使用した、ゲーム AI のビヘイビア ツリーの GDScript 実装。
C# バージョン -> https://github.com/MadFlyFish/godot-behavior-tree-csharp
設置
- 「addons」フォルダーをプロジェクトのメイン ディレクトリにコピーします。
- プロジェクト設定からプラグインを有効にしてから Godot を再起動します。そうしないと、新しいクラスが認識されません (これはエンジンのバグです)。
- オプションで、bt_example フォルダーをプロジェクトのメイン ディレクトリにドラッグすることもできます。
- サンプルが動作していることを確認するには、agent.tscn シーンを実行します。 ex_behavior_tree.tscn シーンは、ツリーがどのように構築されるかを示す例です。
説明書:
- ノード作成アイコンをクリックします。利用可能な新しいノードが表示されるはずです (表示されない場合は、Godot を再起動してください)。 BehaviourTree をルート ノードとして使用する必要があり、子は 1 つだけ持つ必要があります。この子は、BTNode カテゴリの下の任意のノードにすることができ、すべて BTNode クラスから継承します。
- 動作ツリーを作成した後、AI (エージェント) の所有者が誰であるか、およびどの Blackboard が使用されているかを指定する必要があります。黒板はどこにでも置くことができ (木の外にある場合)、異なる木の間で共有することもできます。このシステムは柔軟性が高く、黒板データをいつどのように更新するかを決定できます。たとえば、黒板の更新を処理するスクリプトを使用してプレーンなノードを作成できます。シグナルコールバックを使用したり、process() 内で使用したりすることもできます。または、ツリー内など、他のどこからでも実行できます。保守および追跡できる方法で設計するようにしてください。
- ビヘイビア ツリー フローはその子をそれぞれ実行し、何らかの成功または失敗の状態を返します。成功したノードに続くブランチのみが実行されます。 BTNode は成功または失敗のいずれかを返す必要があり、yield() 呼び出しでのみ実行を一時停止できます。その後、実行が完了するまで実行状態が維持されます。 BTNode が実行状態にある場合、すべての子が実行を完了するまで、ツリーは実行を段階的に一時停止します (唯一の例外は BTParallel )。これは最適化を目的としています。
- ツリーのフローは、いわゆる複合ノード (BTSequence、BTSelector、BTRandomSelector、BTRandomSequence、BTParallel) によって定義され、これらはすべて BTComposite から継承されます。すべての子が成功するとシーケンスは成功しますが、子の 1 つが失敗するとシーケンスは失敗します。セレクターは論理的に逆で、1 つの子が成功すると成功し、すべての子が失敗すると失敗します。並列ではすべての子が実行され、子の実行が完了するのを待つことなく、常に成功します。基本複合ノードはすべての子を実行し、常に成功しますが、実行の完了も待機します。
- AI 動作のアクションは BTLeaf ノードで実行されます。 BTLeafを追加し、「スクリプトの拡張」を実行します。 _tick()メソッドをオーバーライドすることで、このスクリプトで独自の動作を定義できるようになりました。あなたの行動がここに反映されます。ベスト プラクティスを知るために、基本スクリプトのコメントを必ず読んでください。 BTLeaf には子があってはならないことにも注意してください。
- BTDecorator は、子ノードの実行をカスタマイズするために使用されます。彼らは子供を1人だけ持つことができます。
- BTConditional は、最も一般的なタイプのデコレータです。 BTConditional を追加してスクリプトを拡張し、 _pre_tick()メソッドをオーバーライドして、子が実行される条件を定義します。役立つ例が記載されているので、必ずコメントを読んでください。
- BTGuard は、ブランチを一時的にロックするために使用できるデコレータです。オプションで、指定されたロック時間をオーバーライドするロック解除機能を割り当てることができます。ロッカーを割り当てるオプションもあります。 BTGuard は、不必要な分岐や繰り返しを回避するため、動作を非常にリッチかつ反応性に優れたものにし、最適化することができます。
- 他のデコレータを使用すると、実行をループしたり、ティックの結果を反転したりすることができます。デコレータを使用して実行をカスタマイズすることで、できることはたくさんあります。
- 提供されたノードを使用し、動作ツリーの設計パターンに従うことをお勧めします。ただし、これはビジュアル エディターを使用しない純粋なコード ベースの実装であるため、設計を大幅に制御できるため、誤差が許容されます。これらは、いくつかの「グッド プラクティス」に従っている単なる便利なスクリプトですが、いくつかの基本的なルールがない限り、それに拘束されることはありません。ビヘイビア ツリーをどのように設計するかを決定するのはあなた次第ですが、ビヘイビア ツリーを誤って使用すると、ビヘイビアー ツリー パターンの力の恩恵を受けられなくなることに注意してください。 (たとえば、ベースの BTNode をすべてに使用し、毎回それを拡張するだけということもできますが、それは面倒になります)
- 巨大なビヘイビア ツリーを作成することもできますが、ベスト プラクティスは、Godot のコンポーネントの哲学に従い、シーンのコンポーネントごとにいくつかの小さなビヘイビアー ツリーを作成することです。たとえば、動作コントローラーのツリー、武器コントローラーのツリー、パスファインダー コンポーネントのツリーなどです。ビヘイビアー ツリーには黒板を 1 つだけ持つことができますが、同じ黒板は多くのツリーで使用できるため、これは次のようになります。複数の黒板を作成せずに複数の木を置きたい場合に特に便利です。個人的には、黒板を分離コンポーネントとして使用した理由は、同じデータを共有しながら独立して動作する敵の分隊を作りたかったためです。そのため、これはその使用例です。さらに、通常、アクターには複数のコンポーネントがあり、異なるツリーに同じデータベースを使用したいと考えています。