Execute Taskによる実行フローの階層化

前回までの作業がまだ済んでいない場合は、基本的な使い方から前回までのチュートリアルを先に済ませてください。

このチュートリアルで使用するLogic Toolkitのバージョンは1.10.0です。
それより古いバージョンを使用している場合は先に更新してから続きをお読みください。

今回はExecute Task関連のコンポーネントを使用して実行フローの階層化をしてみましょう。
内容は以下の通りです。

  • Logic Behaviorコンポーネントの付いたGameObjectを作成する。
  • Logic Editorウィンドウでグラフを開いて編集する。
  • Execute Taskで子ノードを実行。
  • Switch Execute Taskで子ノードを選択的に実行。
  • If Execute Taskで子ノードを選択的に実行。

シーンを新規作成

他のシーンを開いていると混乱の元となりますので、シーンを新規作成しましょう

  • メニューからFile > New Sceneを選択
  • New SceneウィンドウでBasic (URP)を選択
  • Createボタンをクリック

Logic Behavior付きGameObject作成

シーンにLogic Behaviorコンポーネントが追加された状態のGameObjectを作成します。

  • Hierarchyの+ボタンをクリック
  • メニューからLogic Toolkit > Logic Behaviorを選択
  • 名前はそのままEnterキーで確定。

Logic Editorウィンドウで開く

Logic BehaviorコンポーネントのグラフなどはLogic Editorウィンドウで編集します。
ウィンドウが表示されていない場合は、GameObjectを選択してInspectorの「Edit」ボタンをクリックすることで表示されます。

  • Logic Behaviorオブジェクトを選択
  • InspectorウィンドウのLogic BehaviorコンポーネントのEditボタンをクリック

すでにLogic Editorウィンドウが表示されている場合は、HierarchyウィンドウでのGameObject選択と連動してグラフが切り替わるようになります。

Stateノードの作成

今回はStateノードでExecute Taskコンポーネントを使用します。

  • Startノードの実行出力ポートをドラッグ
  • 右側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からStateを選択
  • ノード名はそのままEnterキーで確定

Execute Taskの追加

StateノードにExecute Taskコンポーネントを追加します。

  • StateノードのComponentsの+ボタンをクリック
  • ノードコンポーネント追加メニューからTasks > Execute Taskを選択

Execute Taskについて

Execute Taskは、Executeポートの接続先ノード(以降、便宜的に子ノードと呼びます)を実行するためのTaskComponentです。

これを使用することで、実行フローを簡単に階層化できます。
つまり「Stateを親ノード、Execute Taskの接続先を子ノードとした階層構造」になります。

Condition Evaluateの追加

Stateが遷移したらExecute Taskの子ノード実行終了を確認できるようにしましょう。
StateノードにCondition Evaluateコンポーネントを追加します。

  • StateノードのComponentsの+ボタンをクリック
  • ノードコンポーネント追加メニューからEvaluators > Condition Evaluateを選択

もう一つStateノードの作成

Condition Evaluateからの遷移先ノードを作成します。

  • Condition EvaluateのCompletedポートをドラッグ
  • 既存のStateノードの下側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からStateを選択
  • ノード名はそのままEnterキーで確定

遷移されたことが分かればよいので中身は設定しません。

Wait For SecondsのTaskノード作成

次に、Execute Taskの子としてWait For Secondsを使用します。

  • Execute TaskのExecuteポートをドラッグ
  • 右側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からTasks > Wait For Secondsを選択
  • ノード名はそのままEnterキーで確定

実行ワイヤーについて

これまでのチュートリアルでも、StartノードやIfノード、Eventノードなどに使用してきましたが、詳細な説明を行っていませんでした。
この実行ワイヤーが本領発揮できるのは今回のような実行フローの階層化に使用する場合ですので、今回は詳細に説明します。

実行ワイヤーは「接続先のノードとそのノードから遷移ワイヤーによって接続されるノード群(実行フローのグループ)」を実行するためのワイヤーです。
親ノード側が実行ワイヤーの接続先ノード(子ノード)を実行し、子ノードはそれぞれの条件によって次々と遷移していきます。
親ノード側が実行終了すれば、子ノード側の実行状況に関わらず子ノードの実行も強制終了します。
今回の場合であれば、Condition Evaluateから2個目のStateに遷移するとWait For Secondsやその接続先が実行途中であっても終了します。

実行ワイヤーの接続先ノード群(遷移ワイヤーによって繋がっているノード)が実行フローのグループとみなされます。
今回の場合であれば「2個のStateノードの繋がりが親ノード側の実行フローグループ」、「Wait For Secondsからの繋がりが子ノード側の実行フローグループ」ということになります。

StateノードとWait For Secondsはグループが異なるため、試しにCompletedポートから既存のStateノードに接続してみると、異なるグループへの接続が切断されてから繋ぎなおされます。

動画のように試してみた方はCondition EvaluateからStateに繋がるように戻しておいてください。

ひとまず「実行ワイヤーから先は子の実行フローグループとして実行される。異なる実行フローのグループ同士は合流できない」と覚えてください。

Wait For Secondsの設定

1秒待機するように設定します

  • Secondsフィールド1に設定

Switch Execute TaskのTaskノード作成

次に、Wait For Secondsからの遷移先にSwitch Execute Taskを作成します。

  • Wait For SecondsのCompletedポートをドラッグ
  • 右側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からTasks > Switch Execute Taskを選択
  • ノード名はそのままEnterキーで確定

Switch Execute Taskについて

Switch Execute TaskはExecute Taskの一種で、実行先を条件によって切り替えできます。

説明のために設定済みの画像を掲載しています。

Valueフィールドと各要素のWhenフィールドが一致するThenポートの接続先ノード(子ノード)を実行します。
一致する要素がなければDefaultポートの接続先ノードを実行します。
Switch On Executeフィールドがオンの場合は、実行中も毎フレーム入力値の判定を行い実行先を切り替えます。

判定する値の型も変更できますが、今回はint型のまま組んでいきましょう。

Switch Execute Taskの設定

Switch Execute Taskで子ノードを切り替えて実行するように設定します。

  • Casesの数を2に設定
  • 2個目のWhenフィールド1に設定
  • Switch On Executeフィールドをチェック

Wait For SecondsのTaskノードの作成

Switch Execute Taskの子ノードを作成していきます。

  • Switch Execute TaskのCasesの1個目のThenポートをドラッグ
  • 右側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からTasks > Wait For Secondsを選択
  • ノード名はそのままEnterキーで確定

Wait For Secondsの設定

1秒待機するように設定します

  • Secondsフィールド1に設定

Stateノードの作成

作成したWait For Secondsの遷移先にStateノードを作成します。

  • 直前に作成したWait For SecondsのCompletedポートをドラッグ
  • 右側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からStateを選択
  • ノード名はそのままEnterキーで確定

Wait For SecondsとStateの複製

既存のノードを複製して2個目のThenポートの接続先を作成します。

  • 直前に作成したWait For SecondsとStateノードを選択
  • Ctrl C (Win) / ⌘ C (Mac)を入力しコピー
  • 下側付近で Ctrl V (Win) / ⌘ V (Mac)を入力しペースト

2個目のThenポートと複製したノードの接続

2個目のThenポートの接続先を設定します。

  • Switch Execute TaskのCasesの2個目のThenポートをドラッグ
  • 複製したWait For Secondsの実行入力ポートにドロップ

If Execute TaskのTaskノード作成

Defaultポートの接続先にIf Execute Taskを使用するTaskノードを作成します。

  • Switch Execute TaskのDefaultポートをドラッグ
  • 先ほど複製したWait For Secondsのノードの下側付近でドロップし、ノード作成メニューを開く
  • Scriptsタブを選択
  • 一覧からTasks > If Execute Taskを選択
  • ノード名はそのままEnterキーで確定

If Execute Taskについて

IfExecuteTaskはSwitch Execute Taskと同様に、実行先を条件によって切り替えできます。

説明のために設定済みの画像を掲載しています。

Conditionsの上から順にInputフィールドのbool値を判定し、最初にtrueだったThenポートを実行します。
条件を満たす要素がなければ、Elseポートの接続先ノードを実行します。
Switch On Executeフィールドがオンの場合は、実行中も毎フレーム入力値の判定を行い実行先を切り替えます。

If Execute Taskの設定

If Execute Taskで子ノードを切り替えて実行するように設定します。

  • Conditionsの数を2に設定
  • Switch On Executeフィールドをチェック

Wait For SecondsとStateの複製

  • Switch Execute Taskの子ノードとして作成したWait For SecondsとStateノードを選択
  • Ctrl C (Win) / ⌘ C (Mac)を入力しコピー
  • If Execute TaskのThenポートの右側付近で Ctrl V (Win) / ⌘ V (Mac)を入力しペースト
  • 3個になるように、縦に並べるようにもう2回ペーストする

If Execute Taskと複製したノードの接続

  • If Execute TaskのConditionsの1個目のThenポートと複製した1個目のWait For Secondsの実行入力ポートを接続
  • 2個目のThenポートと複製した2個目のWait For Secondsの実行入力ポートを接続
  • Elseポートと複製した3個目のWait For Secondsの実行入力ポートを接続

プレイして確認

ここまで作成するとグラフは以下のようになっています。

プレイボタンを押して挙動を確認します。

  • Execute Taskが最初のWait For Secondsを実行して1秒待機することを確認
  • Switch Execute Taskの動作確認
    • Whenフィールド0のThenポートの接続先ノードを実行することを確認
    • Valueフィールド1に変更すると、Whenフィールド1のThenポートの接続先ノードを実行することを確認
    • Valueフィールド2に変更すると、Defaultポートの接続先ノードを実行することを確認
  • If Exeucte Taskの動作確認
    • Elseポートの接続先ノードを実行することを確認
    • 1個目のInputフィールドをチェックすると、そのThenポートの接続先ノードを実行することを確認。
    • 2個目のInputフィールドをチェックしても、そのThenポートの接続先ノードは実行されないことを確認(上から順番に判定して最初にtrueとなったポートのみ実行するため)
    • 1個目のInputフィールドのチェックを外すと、2個目のThenポートの接続先ノードを実行することを確認。
  • Condition EvaluateのConditionフィールドをチェックすると、子ノードの実行も終了することを確認。

補足

Behavior TreeノードでもExecute Taskなどが使える

Execute TaskなどはTaskComponentの一種なので、Behavior Treeノードにも使用できます。

つまり、StateノードでBehavior Tree ExecuteなどのCompositeComponent、Behavior TreeノードでExecute TaskなどのTaskComponentを使用すれば、ステートとビヘイビアツリーの階層化を1枚のグラフ内に組むことができます。

子ノードの実行結果

子ノードの実行フローグループの結果を親ノードに伝えたい場合はCompleteノードが使用できます。

Completeノードに遷移した瞬間に実行を終了し、Resultフィールドの値を親ノードのExecute Taskなどが受け取ります。
もしExecute TaskがBehavior TreeノードであればResultの値を成功/失敗として、さらなる親ノードのSelectorなどに返します。
また、Stateに使用したTaskComponentの実行結果はCompletedポートにシグナルとして送信されます。
実行結果が失敗となる可能性があるTaskComponentはSignal関連ノードで遷移判定してください。

実行フローが深く階層化されている場合であっても、子ノードのグループのCompleteノードのみ受け取ります。
階層化している場合は結果の受け渡しにもご注意ください。

おわり

以上でチュートリアル「基本的な使い方」も終了となります。

他にも簡単なゲームを作成する実践的なチュートリアルもありますので、ぜひ試してみてください。
チュートリアル一覧はこちら

試用版でお試しの方は、お気に召しましたらアセットストアにてご購入ください。