はじめに
通称「極め本」完了後、シティビルダー系のシミュレーションゲームを作る際に躓いたので記録。
ビヘイビアツリーで複数の工程を含む労働等のNPCの行動を実装したところ、労働中にゲームをセーブするとロードした際に労働の進捗が失われてしまったため、この問題の解決策を調べた。
UEのバージョンは5.3.0
前提知識・技能
ビヘイビアツリーを用いたAIの作成
セーブとロードの実行
解決方法
概要
ビヘイビアツリーはRootから順番にノードを実行するため、特定のタスクから再開するという機能は標準では実装されていない。
そこで、以下のようにセーブ時のタスクまでスキップするよう実装した。
- ゲームのセーブ時に再開するタスクの情報を保存する
- ゲームのロード時に再開するタスクの情報を読み込む
- NPCにboolean型の変数を追加し、タスクの開始時にロードが必要か判定する
- ロードが必要な場合、ロード時のタスクを確認し、実行中のタスクとクラスが一致する場合のみ労働を行う
詳細
-
全体像
多数のタスクで同様の処理を行うため、『BTTask_BlueprintBase』クラスを親とするオブジェクト『BTTask_BlueprintBase_WithSave』を作成し、行動内容を書くタスクはそれを継承するようにした。
『BTTask_BlueprintBase_WithSave』のイベントグラフの全体像は以下のようになった。
1つ目のBranchでロードが必要か判定し、必要であれば次の分岐に進む。キャラクター側でObjectのクラスを格納する変数『TaskToDo』が実行中のタスクのクラスと一致する場合のみDoTask関数でタスクを実行する。
タスクの処理内容は継承した子クラスでDoTask関数をオーバーライドして記述する。
-
ビヘイビアツリー内のMoveToやWaitなどのノードを自作のタスクに置き換える
セーブ機能を使うためにMoveToなどのビヘイビアツリー内のノードを自作のタスクに置き換える必要がある。また1つのビヘイビアツリー内で同じタスクを複数回呼び出すとロード時に正しいタスクから再開できないので、Wait1、Wait2など同じ処理内容のものを複数作成する必要がある。後は普通にセーブとロードで変数を読み書きすれば完成。
結果
非ロード時に無駄な処理が増えるのが気になるが欲しい機能は得られた。もっと良い方法があれば後程改良したい。