ビヘイビアツリーのクイックスタートガイド

このガイドでは、Behaviour Tree (ビヘイビアツリー) を使用してプレーヤーをパトロールまたは追跡する AI キャラクタの設定方法について説明します。

ビヘイビアツリーのクイックスタートガイド では、プレーヤーを見て反応し、追跡する敵の AI の作成方法について学習します。プレイヤーを見失うと、数秒後 (この長さは好みに応じて調整できます) に AI は追跡をあきらめて、以下のビデオの例のようにプレイヤーを再び発見するまでランダムに周囲を移動します。

このガイドを修了すると、次のシステムについて理解できるようになります。 

  1. ブループリント ビジュアル スクリプティング

  2. AI コントローラー

  3. ブラックボード

  4. Behavior Tree

  5. Behavior Tree サービス

  6. Behavior Tree デコレーター

  7. Behavior Tree タスク

1 - 必要なプロジェクト設定

最初のステップでは、AI キャラクターが環境を動き回るために必要となるアセットでプロジェクトを設定します。 

このガイドでは、新規の「サード パーソン ブループリント」テンプレート プロジェクトを使用します。

  1. [Content Drawer (コンテンツ ドロワー)] パネルを展開して、「ThirdPersonBP」フォルダを右クリックし、「AI」という名前で 新しいフォルダ を作成します。

    Open the Content Drawer then right-click on the ThirdPerson folder and create a New Folder called AI

  2. 「ThirdPerson」 > 「Blueprints」 フォルダで、BP_ThirdPersonCharacter「AI」 フォルダにドラッグし、[Copy Here (ここにコピー)] を選択します。

    In the ThirdPerson Blueprints folder drag the BP_ThirdPersonCharacter onto the AI folder and select Copy Here

  3. AI」フォルダには、AI Cotroller クラスを基底クラスとする新しい Blueprint クラスを作成します。

    In the AI folder create a new Blueprint Class based on the AIController class

  4. AIController ブループリントには、「Enemy_Controller」、そして BP_ThirdPersonCharacter ブループリントには、「Enemy_Character」 と名前を付けます。

    Name the AIController Blueprint Enemy_Controller and the BP_ThirdPersonCharacter Blueprint  Enemy_Character

  5. Enemy_Character を開き、グラフからすべてのスクリプトを削除します。

  6. Character Movement コンポーネントを選択し、[Details (詳細)] パネルの [Max Walk Speed]「120.0」 に設定します。

    クリックしてフルサイズで表示

    これにより、プレイヤーの追跡なしでパトロールするときに、AI キャラクターの環境内を移動する速度が低下します。 

  7. ツールバーから [Class Defaults] を選択し、[Details] パネルで 「Enemy_Controller」AI Controller クラス として割り当てます。

    クリックしてフルサイズで表示

    AI をワールドに配置します。ワールドがロードされた後に AI をスポーンする場合は、[Auto Possess AI (AI を自動で所有)] 設定を [Spawned (スポーン済み)] に変更します。

  8. [Content Drawer (コンテンツドロワー)] から 「Enemy_Character」 をレベルにドラッグします。 

  9. [Place Actors (アクタの配置)] パネルから、NavMeshBoundsVolume をレベルにドラッグします。

    From the Place Actors panel drag a NavMeshBoundsVolume into the Level

  10. NavMeshBoundsVolume を選択した状態で、R を押し、ボリュームをスケーリングしてレベル全体をカプセル化します。

    With the NavMeshBoundsVolume selected, press R and scale the volume

    これにより、Navigation メッシュが生成され、AI キャラクターが環境内を移動できるようになります。P キーを押すと、ビューポートでの NavMesh の表示を切り替えることができます (緑色の領域は可能なナビゲーション位置を示します)。

    ゲームプレイ中に、Show Navigation コマンドを使用して、NavMesh の表示のオン / オフを切り替えることができます。

プロジェクトの設定が完了したので、以下のステップで Blackboard アセットを設定します。

2 - ブラックボードの設定

このステップでは、基本的に AI の頭脳である Blackboard アセットを作成します。AI に知らせたいすべての情報には、参照可能な Blackboard Key が含まれています。ここでは、プレイヤーを追跡するためのキー、AI がプレイヤーに対する視線を持っているかどうかのキー、プレイヤーを追跡していないときに AI が移動できる場所に関するキーを作成します。

  1. [Content Drawer][+Add (追加)] をクリックし、[Artificial Intelligence] の下の [Blackboard] を選択して「BB_Enemy」と名付けます。

    In the Content Drawer click  Add and under Artificial Intelligence select  Blackboard and call it  BB_Enemy

  2. BB_Enemy ブラックボード内で、[New Key] ボタンをクリックして を選択します。

    Inside the BB_Enemy Blackboard click the New Key button and select Object

    Blackboard アセットは、次の 2 つのパネルで構成されています。Blackboard Keys (追跡する変数) を追加して追跡できる [Blackboard] と、キーの種類を名前付けして指定できる [Blackboard Details] です。

  3. Object キーの場合、[Entry Name] には 「ElemyActor」 と入力し、[Base Class] には 「Actor」 と入力します。

    For the Object key enter EnemyActor as the Entry Name and Actor as the Base Class

  4. [Key Type]「HasLineOfSight」 と名付けて Bool に設定し、別の Key を追加します。

    Add another Key with the Key Type set to Bool called HasLineOfSight

    これは、AI がプレイヤーに視線を持っているかどうかを追跡するために使用されます。

  5. [Key Type]「PatrolLocation」 と名付けて Vector に設定し、別の Key を追加します。

    Add another Key with the Key Type set to Vector called PatrolLocation

    これは、AI がプレイヤーを追跡していない際の AI が移動可能なレベル内の場所を追跡するために使用されます。

[Blackboard] には、追跡する必要のあるものを設定しています。以下のステップでは、ビヘイビアツリー をレイアウトします。

3 - Behavior Tree レイアウト

このステップでは、ビヘイビアツリー の流れと AI に入力させたい状態についてレイアウトします。ビジュアルフローとして AI があることを想定する状態で ビヘイビアツリー をレイアウトすると、その状態に入るためにはどのようなタイプのロジックとルールを作成する必要があるかを知ることができます。

  1. [Content Drawer][+Add (追加)] をクリックし、[Artificial Intelligence] の下の [Behavior Tree] を選択して 「BT_Enemy」 と名付けます。

    In the Content Drawer click  Add and under Artificial Intelligence select  Behavior Tree and call it BT_Enemy

    命名規則は異なる場合がありますが、名前にはアセット タイプの略語を追加することをお勧めします。

  2. 「BT_Enemy」 を開き、「BB_Enemy」Blackboard アセット として割り当てます。

    Open the BT_Enemy assign the BB_Enemy as the Blackboard Asset

    作成した Blackboard Key が表示されない場合は、黄色い矢印をクリックして Blackboard アセット をクリアしてから、Enemy_BB を再度割り当ててキーを更新します。

    ビヘイビアツリー は、動作を定義するブランチとノードを視覚的にレイアウトする Behavior Tree グラフ、ノードのプロパティを定義できる [Details] パネル、そしてゲームの実行中に Blackboard Key とその現在値を表示しデバッグに有用な Blackboard の 3 つのパネルで構成されています。

  3. グラフで、Root を左クリックしてドラッグし、Selector ノードを追加します。

    In the graph left-click and drag off the Root and add a Selector node

    コンポジット はフロー制御の一つの形式です。これは、コンポジットに接続されている子ブランチがどのように実行されるかを決定します。

    コンポジット

    説明

    Selector

    左から右にブランチを実行します。通常、サブツリー間の選択に使用します。Selector は、正常に実行されたサブツリーが見つかると、サブツリー間の移動を停止します。たとえば、AI がプレイヤーを正常に追跡している場合、AI は実行が終了するまでそのブランチに留まり、Selector の親コンポジットに移動して決定されたフローを続行します。

    Sequence

    左から右にブランチを実行します。一連の子を順番に実行するためによく使用します。Selector とは異なり、Sequence は失敗したノードに到達するまでその子を実行し続けます。たとえば、プレイヤーに移動する Sequence がある場合は、範囲内にあるかどうかを確認してから、回転してアタックします。範囲内にあるかどうかのチェックに失敗した場合、回転アクションおよびアタック アクションは実行されません。

    Simple Parallel

    Simple Parallel には 2 つの「接続」があります。 最初の 1 つは、メインタスクで、Task ノードにのみ割り当てることができます (コンポジットがないことを意味します)。2 つ目の接続 (Background Branch) は、メインタスクの実行中に実行されるアクティビティです。プロパティによっては、Simple Parallel はメインタスクが終了するとすぐに終了するか、Background Branch が終了するのを待ちます。

  4. Selector ノードの場合、[Details] パネルで、ノード名を [Node Name]「AI Root」 に変更します。 

    For the Selector node in the Details panel change the Node Name to AI Root

    グラフ内のノードの名前を変更すると、ノードの実行内容を上位レベルから簡単に識別できます。この例では、子ブランチを切り替えるビヘイビアツリーの実際の「Root」であるため、「AI Root」 と名付けます。ビヘイビアツリーの作成時に自動的に追加されるデフォルトの Root ノードは、ビヘイビアツリーのプロパティの設定や、Blackboard アセットの割り当てに使用します。 

  5. 「AI Root」 を左クリックしてドラッグし、「Chase Player」 という名前の Sequence ノードを追加します。

    クリックしてフルサイズで表示

    AI に一連のアクションを実行するように指示するため、ここでは Sequence ノードを使用します。つまり、プレイヤーに向かって回転し、移動速度を変更してから、プレイヤーの方に移動してそれを追跡します。 

  6. AI Root ノードを左クリックしてドラッグし、「Patrol」 という名前の Sequence ノードを追加します。

    クリックしてフルサイズで表示

    AI の場合、Sequence ノードを使用してマップ上のランダムな場所を見つけ、その場所に移動し、しばらく待ってから、新しい場所を見つけて移動するプロセスを繰り返します。 

    ノードの右上隅の数字にも留意するようにしてください。

    The numbers in the upper-right corner of the nodes

    操作の順序を示します。ビヘイビアツリー は左から右、上から下に実行されるため、ノードの配置は重要です。AI にとって最も重要なアクションは通常左側に配置され、重要性の低いアクション (またはフォールバック動作) は右側に配置されます。子ブランチは同じ方法で実行されますが、子ブランチに障害が発生した場合は、ブランチ全体の実行が停止し、ツリーのバックアップに失敗します。たとえば、Chase Player が失敗した場合、Patrol に移動する前に AI Root に戻ります。

  7. AI Root をドラッグして、[Wait Time]「1.0」 に設定した Patrol の右側に Wait タスクを追加します。 

    クリックしてフルサイズで表示

    このノードは紫色となっていますが、これは Task ノードであることを示しています。Task ノードは、ビヘイビアツリー に対して実行させたいアクションです。Wait タスクは ビヘイビアツリー が Chase Player または Patrol の両方に失敗した場合のキャッチオールとして機能します。 

  8. Chase Player をドラッグして、Rotate to Face BBEntry ノードに追加します。

    クリックしてフルサイズで表示

    この特定の Task を使用すると、回転させてこちらに向けたい Blackboard Entry (この場合は Enemy Actor (プレイヤー)) を指定できます。ノードを追加してから [Details (詳細)] パネルを確認すると、Blackboard Key は自動的に EnemyActor に設定されます。これは、Blackboard Key が Blackboard の Actor 変数をフィルタリングして Actor がリストの最初の変数となっているためです。[Precision (精度)] オプションでは、成功条件の範囲を調整したり、[Node Name (ノード名)] を変更したりできます。

  9. ツールバー から、[New Task (新しいタスク)] ボタンをクリックします。

    From the Toolbar click the New Task button

    ビルトインのタスク以外にも、カスタマイズおよび定義できる追加のロジックを持つカスタム タスクを作成して割り当てることもできます。カスタム タスクは、AI の移動速度を変更して、プレイヤーの後を追うために使用します。新しいタスクを作成すると、新しい ブループリント が自動的に作成されて開きます。

    クリックしてフルサイズで表示

  10. [Content Drawer] で、新しいアセットの名前を 「BTT_ChasePlayer」 に変更します。

    In the Content Browser rename the new asset as BTT _ChasePlayer

    新しく作成した タスクデコレーター、または サービス は、作成時にすぐに名前を変更することをお勧めします。適切な命名規則に従い、アセットの名前に作成するアセットの種類を表す接頭辞を付けます。たとえば、Behavior Tree タスクの場合は BTT、Behavior Tree デコレーターの場合は BTD、そして Behavior Tree サービスの場合は BTS です。 

  11. BT_Enemy の内部には、BTT_ChasePlayer タスクを追加し、続いて Move To を追加します。 

    クリックしてフルサイズで表示

    新しいタスクにはまだロジックがないので、前に戻って AI キャラクターの移動速度を変更するロジックを追加します。その後、AI を EnemyActor (プレイヤー) に移動します。

  12. 新しい タスク を作成し、名前を 「BTT_FindRandomPatrol」 に変更して、Patrol に接続します。 

    クリックしてフルサイズで表示

  13. タスクに Move To タスクを追加し、Blackboard KeyPatrolLocation に設定します。 

    クリックしてフルサイズで表示

    これにより、BTT_FindRandomPatrol タスク内に設定されている PatrolLocation に移動するように AI に指示します。 

  14. Move To タスクの次は、Wait Time「4.0」Random Deviation「1.0」 にして、Wait タスク を追加します。 

    クリックしてフルサイズで表示

    これにより、AI は PatrolLocation で 3 - 5 秒待つように指示されます (Random Deviation により Wait Time に「+」または「-」秒が追加されます)。

これで、ビヘイビアツリー のフレームワークは完成しました。以下のステップでは、AI の移動速度を変更するロジック、AI がパトロールしているときにナビゲートするランダムな位置を見つけるロジック、AI がプレーヤーの追跡やパトロールをするタイミングを決定するロジックを追加します。

4 - タスクの設定 - Chase Player

このステップでは、Chase Player タスク を設定して、プレーヤーを追跡する際の移動速度を変更します。

  1. BTT_ChasePlayer 内で右クリックし、Event Receive Execute AI ノードを追加します。 

    Inside BTT_ChasePlayer right-click and add an Event Receive Execute AI node

    このタスクが ビヘイビアツリー 内でアクティベートされると Event Receive Execute AI ノードが起動します。 

    エージェントが AI コントローラーである場合は、常に AI バージョンの Event Receive ExecuteEvent Receive Abort、そして Event Receive Tick を選択する必要があります。一般的なイベントと AI イベントが両方実装されている場合は、より適する方のイベントが呼ばれることに注意してください。つまり、AI に対しては AI イベント、それ以外は一般的なイベントが呼ばれます。

  2. Controlled Pawn ピンをオフにして、Cast to Enemy_Character ノードを使用します。

    Off the Controlled Pawn pin use a Cast to Enemy_Character node

    ここでは、Cast ノードを使用して、Enemy_Character と呼ばれる AI の Character Blueprint にアクセスします。

  3. [Content Drawer] の中にある Enemy_Character ブループリントを開き、「Update Walk Speed」 という名前の 関数 を追加します。 

    Inside the Content Drawer open the Enemy_Character Blueprint and add a Function called Update Walk Speed

    この関数は、ビヘイビアツリーから呼び出され、AI の移動速度を変更するために使用されます。 

    技術的には、Chase Player タスクで Cast ノードから Character Movement コンポーネントにアクセスし、タスク内から移動速度を調整できますが、ビヘイビアツリーでサブオブジェクトのプロパティを直接変更することはお勧めしません。代わりに、ビヘイビアツリーでキャラクタ内の関数を呼び出し、必要な修正を行います。 

  4. Update Walk Speed 関数の [Details] パネルで、「NewWalkSpeed」 と名付けた Float 入力を追加します。 

    In the Details panel for the Update Walk Speed function add a Float input called NewWalkSpeed

  5. CharacterMovement コンポーネントを [Components (コンポーネント)] タブからドラッグします。 

    Drag the **CharacterMovement** Component off the Components tab

  6. Character Movement のピンをクリックしてドラッグし、Set Max Walk Speed のアクションメニュー タイプ、メニューの Set Max Walk Speed にクリックします。 

    Click and drag off the pin of Character Movement and from the actions menu type in Set Max Walk Speed then click that function from the menu  

  7. Set Max Walk Speed を使用して、以下のように接続します。  

    Use Set Max Walk Speed and connect as shown below

この関数をビヘイビアツリーから呼び出すと、新しい速度として使用される値を渡すことができます。

  1. BTT_ChasePlayer タスクの内部に戻り、As Enemy Character ノードから Update Walk Speed を呼び出して 「500.0」 に設定し、以下のように接続します。

    Back inside the BTT_ChasePlayer Task from the As Enemy Character node call Update Walk Speed set to 500.0 and connect

    作成した Update Walk Speed 関数が表示されない場合、Chase Player タスク に追加する前に、この Enemy_Character ブループリントの コンパイル の実行が必要かもしれません。

  2. Update Walk Speed の次は、Finish Execute ノードを 2 つ追加し、以下のように接続します。

    Following Update Walk Speed, add two Finish Execute nodes and connect

    ここでは、「Enemy_Character」にキャストしたときに、タスクが正常に終了したとマークしています。制御された Pawn が「Enemy_Character」ではない場合は、タスクを失敗としてマークして、タスクを中止するようにこのケースを処理する必要があります。

  3. 新しい [New Walk Speed] ピンを右クリックし、変数に昇格して 「ChaseSpeed」 と名付けます。

    Right-click the New Walk Speed pin then promote it to a variable and call it ChaseSpeed

  4. [ChaseSpeed] では、必ず [Instance Editable] を有効にしてください。

    For ChaseSpeed make sure to enable Instance Editable

    これを Instance Editable 変数に昇格させることで、このブループリントの外部から Max Walk Speed の値を設定して、ビヘイビアツリー 内部のプロパティとして使用することが可能となります。 

    The value of Max Walk Speed can be set from outside of this Blueprint and will be available as a property inside our Behavior Tree

    これで Enemy_Character ブループリントに送られる Chase Speed の値の変更が簡単になり、AI がプレーヤーを追跡する速度を調整することができます。

これで Chase Player Task は完成したので、以下のステップでは AI が移動するランダムな位置を得るための Find Random Patrol Task ロジックを設定します。

5 - タスク設定- Find Random Patrol

このステップでは、AI がプレーヤーを追跡していないときはランダムな位置に移動するように、Find Random Patrol Task を設定します。 

Blueprint Behavior Tree タスクの実装は、迅速に繰り返し処理を行うための良い方法ですが、パフォーマンスが問題となる場合は、そのロジックをネイティブの Behavior Tree タスクに変えることもできます。

  1. BTT_FindRandomPatrol の内部では、Event Receive Execute AI を使用し、Enemy_Character にキャスト してそれらを接続します。

    nside BTT_FindRandomPatrol use Event Receive Execute AI and Cast to Enemy_Character

  2. As Enemy Character をオフにして Update Walk Speed を呼び出したら、New Walk Speed を変数に昇格し、以下のように設定をして 「Patrol Speed」 と名付けます。

    画像をクリックしてフルサイズで表示

    - Variable Name「PatrolSpeed」 に設定
    - Instance Editable「Enabled」 に設定
    - Patrol Speed (Default Value)「125.0」 に設定
    ここでは、パトロール中に敵の移動速度を下げてみます。

  1. [Controlled Pawn]、そして [Get Actor Location] とオフにし、[Branch] に接続された [Return Value] とともに [GetRandomReachablePointInRadius] をオフにします。

  2. 以下の設定で、[GetRandomReachablePointInRadius][Radius] を変数に昇格します。

    画像をクリックしてフルサイズで表示

    - Variable Name「PatrolRadius」 に設定
    - Instance Editable「Enabled」 に設定
    - Patrol Radius (Default Value)「1000.0」 に設定

    ここでは、敵キャラクターの現在位置から 1000 単位以内のランダムな位置を見つけます。また、Branch ノードを使用して、移動先のランダムなポイントが見つからないエッジケースを処理します。

  3. Random Location ピンをオフにして、「PatrolLocation」と名付けた変数に昇格された Key とともに Set Blackboard Value as Vector を使用します。

  4. Get Actor Location から取得した Value を持つ別の Set Blackboard Value to Vector ノードを使用します。

  5. 前のステップに続き、以下の図ように両方のノードに接続すると、Finish Execute と表示され、Success にマークされます。

    画像をクリックしてフルサイズで表示

    敵がランダムな位置を見つけて移動する場合、その移動先が Blackboard に保存されます。位置が見つからない場合は、現在位置が使用され、新しい位置を試す前にその位置に留まります。Controlled Pawn が Enemy_Character ではないエッジケースを処理する必要があります。

  1. Cast ノードの Cast Failed ピンをオフにし、[Success] を無効にした状態で [Finish Execute] を使用します。

    画像をクリックしてフルサイズで表示

    Controlled Pawn が Enemey_Character でない場合、このタスクは失敗としてマークされ、中止されます。

これで Find Random Patrol Task の設定は完了です。以下のステップでは、デコレーター の詳細や、それらを条件式として使用する方法や AI コントローラーの設定ついても学習します。

6 - AI コントローラーの設定

このステップでは、最後のステップに備えて AI コントローラーの内部で少し作業を行ってから デコレーター を設定し、ビヘイビアツリー のどのブランチに入力するかを決定します。 

  1. [Content Drawer] で、Enemy_Controller ブループリントを開き、Event On Possess ノードを追加します。 

  2. Event On Possess をオフにし、[BTAsset]「BT_Enemy」 に設定した Run Behavior Tree ノードを追加します。 

    Off Event On Possess and add a Run Behavior Tree node with BTAsset set to BT_Enemy

    Run Behavior Tree は、AI コントローラー クラス ブループリントを対象としたコンテキストの関数呼び出しで、割り当てられた Behavior Tree アセットを実行できるようにします。

  3. [Components (コンポーネント)] ウィンドウで、[+ Add (追加)] をクリックし、「AIPerception Component」 を検索して追加します。

    In the Components window click Add Component and search for and add an AIPerception Component

    AI Perception コンポーネント は、AI Perception System 内に刺激リスナーを作成するために使用され、応答可能な登録済みの刺激 (私たちの場合、視覚を使います) を収集します。これにより、AI が実際にプレーヤーを認識し、それに応じて反応できるタイミングを判断できるようになります。

  4. AIPerception コンポーネント[Details] パネルで、[AI Sight config] を追加し、[Detect Neutrals] を有効にします。

    In the Details panel for the AIPerception Component add an AI Sight config and enable Detect Neutrals

    Detection by Affiliation プロパティを使うと、同じ所属のチームメートと対戦したり、対立する所属メンバーを攻撃したりするチームベースの AI を設定できます。デフォルトでは、アクタ には所属が割り当てられず、中立と見なされます。

    現時点では、ブループリントを使って所属を割り当てる方法はありません。そのため、プレーヤーを検出するために、[Detect Neutral] フラグを有効にします。別の方法として、どのキャラクターがプレーヤーであるかを決定するために Actor Tagging を使用し、AI キャラクター (達) がプレーヤーとしてタグ付けされたアクタのみを強制的に追跡するようにします。

  5. [AIPerception][Events] セクションで、[On Target Perception Updated] の横にある [+] 記号をクリックします。

    In the Events section for AIPerception click the plus sign next to On Target Perception Updated

  6. グラフの [On Target Perception Updated] をオフにし、「Player」 として タグ を設定した Actor Has Tag ノードを追加します。  

    Off On Target Perception Updated in the graph and add an Actor Has Tag node with Tag set to Player

  7. Stimulus ピンをオフにして、Break AIStimulus ノードを追加します。

  8. 以下に示す ConditionBranch ノードを追加します。 

    Add a Branch node with the Condition

    ここでは、アクタが正常に感知されたかどうか、そしてアクタにプレーヤーのタグがあるかどうかを確認します。 

    Break AIStimulus ノードを選択すると、[Details] パネルで [Hide Unconnected Pins] を使用して接続されていないすべてのピンを非表示にし、上の図のようにグラフを表示できます。

  9. BranchFalse をオフにし、そして [Time]「4.0」 にして [Set Timer by Event] を使用します。 

  10. 右クリックして Time を変数に昇格し、「Line Of Sight Timer」 と名付けます。 

    クリックしてフルサイズで表示

    この変数と割り当てられた値によって、AI がプレーヤーの追跡を中止するまでの時間が決定されます。この時間を過ぎると、アタッチされたイベントが実行されます。 

  11. [Set Timer by Event][Return Value] を右クリックし、「EnemyTimer」 と名付けて変数に昇格します。 

    クリックしてフルサイズで表示

    これにより、ハンドル を使用して Timer への参照が格納されます。このハンドルは、スクリプトから呼び出されてハンドル自体を無効にし、関連付けられたイベント (関連するイベントの実行を妨げます) をクリアします。これは後で、「Line of Sight Timer」が切れる前に AI がプレイヤーを再確認するイベントに使用できます。これにより、AI がプレイヤーを見失って追跡を放棄するのを防ぐことができます。 

  12. Custom Event を作成して、そのイベント名を 「StartEnemyTimer」 とし、Set Timer by EventEvent ピンに接続します。 

    クリックしてフルサイズで表示

  13. 右クリックして、[Variables]>[AI] の下に Get Blackboard ノードを追加します。

    Add a Get Blackboard node under Variables  AI

  14. ブラックボード をオフにし、Set Value as BoolSet Value as Object を使用して、以下のように接続します。 

    Off Blackboard and use Set Value as Bool and Set Value as Object and connect

    これにより、新しい値で定義された Blackboard Key を更新することができます。 

  15. 両方の Key Name で右クリックして、それぞれ 「HasLineOfSight」「EnemyActor」 と名付けて 変数 に昇格します。 

  16. ブループリントを コンパイル し、両方の Key Nameデフォルト値 をそれぞれ 「HasLineOfSight」「EnemyampActor」 に設定します。 

    クリックしてフルサイズで表示

  17. Branch[True] をオフにして、Get EnemyTimer を使用した後に Clear and Invalidate Timer by Handle を使用します。 

    クリックしてフルサイズで表示

    AI は プレーヤーを認識すると、再びプレーヤーを認識できなくなるまで Line Of Sight Timer をクリアします (新しい Line Of Sight Timer が開始されます)。 

  18. 以下の図に示すように、Blackboard ノード、Set Value as、そして Key Name ノードをコピーして貼り付けます。 

    クリックしてフルサイズで表示

  19. Set Value as Bool ノードで、[Bool Value] を有効にし、図のように アクタ ピンを [Object Value] までドラッグします。 

    クリックしてフルサイズで表示

    これは、Has Line Of SightBlackboard Key Values「True」 に、EnemyActor を知覚する 「Actor」 に設定します (これがプレイヤーである場合のみ起動するように設定されています)。 

  20. [Compile] をクリックしてコンパイルし、ブループリントを閉じます。

    クリックしてフルサイズで表示

    最終的なグラフは上の図のようになります。

7 - デコレーターと最終設定

この最後のセクションでは、Player Character と Enemy Character ブループリントの設定をいくつか調整します。また、ビヘイビアツリー には、指定された条件に基づいて入力可能なブランチを決定する デコレーター を設定します。 

  1. [Content Drawer][Content]>[ThirdPersonBP]>[Blueprints] の下にある 「ThirdPersonCharacter ブループリント」 を開きます。

  1. [Details] パネルで、タグ を検索して追加し、「Player」 に設定します。 

    ![ In the Details panel search for and add a Tag set to Playerbtqs-step-6-18.png)

    この「Player」のタグを追加すると、AI がプレーヤーを認識して反応できるようになります。 

  2. 「AI」フォルダの中にある Enemy_Character ブループリントを開きます。 

  3. [Details] パネルで [Rotation] を探して、[Use Controller Rotation Yaw] を有効にします。 

    n the Details panel, search for Rotation and enable Use Controller Rotation Yaw

    これにより、ビヘイビアツリー から Rotate to Face BB Entry が呼び出されたときに AI が正しく回転するようになります。 

    Pawn オプションが表示されない場合は?最初にツールバーの [Class Defaults] ボタンをクリックする必要があります。

  4. 「BT_Enemy」 を開いて [Chase Player] を右クリックし、[Add Decorator...] の下の [Blackboard] をクリックします。 

    クリックしてフルサイズで表示

    ビヘイビアツリー でノードを右クリックすると、追加機能を提供するサブノードを追加できます。 

    サブノード

    説明

    Decorator

    条件式としても知られています。他のノードにアタッチされ、ツリーのブランチあるいはノード 1 つでも実行可能かどうかの判断をするノードです。

    サービス

    これらは、Task ノードと Composite ノードにアタッチされ、ブランチの実行中に定義された頻度で実行されるノードです。多くの場合、ブラックボード の確認や更新に使用されます。これらは、他の Behavior Tree システムの従来の Parallel ノードに代わるものです。

    Blckboard デコレーター を使用して Blackboard Key の値を決定します。これが有効な場合、このブランチの実行を許可します。 

  5. 追加された Blackboard Based Condition を選択し、[Details] パネルで以下の設定を行います。 

    クリックしてフルサイズで表示

    • [Observer Aborts]「Both」 に設定

    • [Blackboard Key]「HasLineOfSIght」 に設定

    • [Node Name]「Has Line of Sight?」 に設定

    ここでは、[HasLineOfSight] の値が「Is Set」 の場合 (または、true) には、この Chase Player ブランチを実行するように指定しています。[Observer aborts] の設定が 「Both」 の場合は、Blackboard Key に変更を割り当てると、自分自身 (Chase Player) とそれよりも優先度の低いタスクを中止することができます。つまり、HasLineOfSight の値が変更されて設定されていない場合は、自身 (Chase Player) を中止し、その時点で次のブランチ (Patrol) が実行されます。HasLineOfSight 値が再び 「Is Set」 になると、Observer は優先度の低いタスクを中止し、Chase Player ブランチを実行することができます。 

  6. エディタで [Compile] をクリックして、 ビヘイビアツリー を閉じ、[Play] します。

最終結果

これで AI をテストできるようになり、AI がユーザーを認識したときに追跡を始めます。

AI は、ユーザーを見失った場合でも、ユーザーを追跡して視線を取り戻そうとします。Line Of Sight Timer の値に入力した時間が過ぎると、追跡を諦めてパトロールに戻ります。

再生中に動作中の ビヘイビアツリー を見て、ビヘイビアツリーがブランチ間でどのように切り替わるかを確認することができます。再生中に ビヘイビアツリー 内で変数を監視して、AI の現在値を知ることもできます。

8 - 応用編

これで、AI キャラクターがプレーヤーを追跡し、指定された時間内にプレーヤーを見失った後は再び巡回するようになったので、次の要素を ビヘイビアツリー に追加してみてください。

  • ビヘイビアツリー で、両方の Move To タスクに、それに先行する タスク からの機能を組み込んだ新しい サービス を追加します。

    • オリジナルの ビヘイビアツリー は、移動速度を調整し (プレイヤーを追いかける場合)、ランダムに移動する位置を探索したり移動速度を遅くするため (パトロールの場合) に、別々の タスク を使用します。これらを Move To タスク にアタッチされている サービス に変換します。

    • ヒント:サービス のスクリプトは各 タスク のスクリプトに似たものになりますが、Event Receive Execute AI の代わりに Event Receive Activation AI を使用することをお勧めします。なぜならこれらは サービス であるため、Finish Execute ノードも必要ありません。

  • ランダムなパトロール地点を使用して移動する代わりに、AI が移動できるベクター値の 配列 変数を含む Patrol Path ブループリント を作成します。

    • ヒント: 巡回して配列内の次のエントリを取得し、その位置間で AI を移動させてから、配列内の現在のエントリに基づいて Blackboard Key の値の PatrolLocation を更新します。

  • プレーヤーの視線が失われた場合は、プレーヤーの現在の場所を取得するのではなく、AI をプレーヤーの最後の既知の位置に移動します。

    • ヒント: Turning and Chasing the PlayerMove To コマンドでは、現在 (プレーヤーの現在の位置を取得する) EnemyActor の位置を取得するように設定されているため、EnemyActor の代わりに位置を指定する必要があります。

  • プレイヤーに接触したら、AI にアタック機能を追加します。

    • ヒント: Turning and Chasing the PlayerBackground タスク として新しい Composite ノードを追加します。AI がプレーヤーに接触したら、アタック アニメーション用の Task ノードを追加します。