【Unity】RPGを作るチュートリアルその53 行動処理の全体を管理するクラス
- 2025.03.27
- RPGチュートリアル
- RPG, Unity, ゲーム開発, チュートリアル

シンプルなRPGをUnityで作るチュートリアルシリーズの53回目です。
第52回では敵キャラクターの行動を決定するクラスを作成しました。
今回は行動選択を行うクラスを実装していきます。全体の処理を管理するクラスについては作成済みのため、登録以外の処理について実装していきます。その後、個別の行動を処理するクラスの作成に進みたいと思います。
制作環境
MacBook Pro 2023 Apple M2 Max
Unity6 (6000.0.30f1) Silicon
作業内容と順序
シンプルなRPGを作る上でどんな作業が必要か、どんな順番で作っていくと良さそうか、別ページで検討しました。基本的にこの流れに沿って進めていきます。
チュートリアルの一覧
このシリーズ全体の一覧は以下のページにまとめています。
前回の内容
前回は敵キャラクターの行動を決定するクラスを作成しました。
行動処理の全体を管理するクラス
敵味方ともに、選択した行動をどんな順番で処理していくのかを管理するクラスに処理を実装していきます。攻撃や魔法など、各行動に応じた具体的な処理については後の回で作成する別クラスに任せるとして、選択した行動の優先度決定、処理の制御などを行う部分を実装していきましょう。
このクラスのスクリプトファイルは作成してあるので、以下の機能を追加していきましょう。
- アクション間の実行間隔を決めるフィールド
- 参照用フィールド
- 実行中のコルーチンを保持するフィールド
- プロセスの実行状態やメッセージの表示状態を保持するフィールド
- 初期化用のメソッド
- 行動リストの要素の優先度を設定するメソッド
- 行動リストの内容を優先度に応じて処理するメソッドとコルーチン
- 行動処理のコルーチンを停止させるメソッド
- 敵味方のキャラクターのパラメータを取得するメソッド
- 敵味方のキャラクターの名前を取得するメソッド
- 次のメッセージを表示するメソッド
- 行動の処理(プロセス)の実行状態を切り替えるメソッド
- メッセージの表示状態を切り替えるメソッド
- デバッグ用: キャラクターの行動順をコンソールに出力するメソッド
やることがいっぱいになりました。優先度決定や全体の処理の進行制御に加えて、計算や画面の表示に必要な項目を取得する便利メソッドだったり、状態を制御するメソッド、デバッグ用のメソッドを加えています。
これを踏まえて、コードの形にしていきます。まずは全文を表示して、個別に説明を行いたいと思います。
各種メソッドを追加していることから、先頭のusingディレクティブも追加してあります。
フィールド
フィールドについては、以前用意していた「_actions」の項目に加えていくつか追加しています。
「_actionInterval」は各行動のインターバルとなる時間で、味方の攻撃、敵の攻撃と進む際に間の時間を定義します。メッセージの表示間隔はデフォルトで0.5秒にしているので、行動のインターバルが0だと感覚的に早く進みすぎることもあり、多少の待ち時間を入れています。ユーザがメッセージを読み取る時間も必要になるので、この値はInspectorウィンドウから変更できるようにしています。
「BattleManager」への参照は処理完了の通知を行なったり、状態を確認するのに使います。「EnemyStatusManager」は敵キャラクターのパラメータや名前を取得するのに使います。
「_processActionCoroutine」は行動を処理するコルーチンを格納するものです。例えば味方、敵の順で行動する際に、味方の攻撃で敵を倒した場合、敵の行動処理には進まず、処理用コルーチンを止めるようにします。そのために現在動いているコルーチンを保持しておく必要があるので、フィールドとして用意しています。
「IsPausedProcess」はプロセス全体をポーズするかどうかのフラグ、「IsPausedMessage」はメッセージ表示が完了するまで待つかどうかのフラグです。プロセス全体をポーズさせるのは、攻撃の一連の処理が完了するまで待つ、魔法の一連の処理が完了するまで待つ、といった行動ごとに待ち合わせを行うことを想定しています。メッセージのポーズは、攻撃の中で「スライムの攻撃!」で待つ、「アレンに5のダメージ!」で待つ、といったメッセージ単位でのポーズを想定しています。
初期化処理
初期化処理では、「BattleManager」への参照を受け取って、必要なものをフィールドにアサインしていきます。現時点ではこの2つの処理ですが、各行動を処理するクラスの作成が終わったら、そちらのクラスの初期化処理もここで呼び出したいと思います。
優先度の設定
優先度を設定するメソッドです。まずは行動リスト内の素早さに補正をかけます。仕様として乱数幅20%にしているので、素早さの値に0.8から1.2をかけたものを計算に使用します。
計算された素早さを使ってリストを並べ替え、素早さの低い順に優先度を1, 2, 3, …と割り当てていきます。逃走については最優先で処理させるため、優先度を100に設定します。今回のチュートリアルだと行動するキャラが2人のため優先度100なら最優先になりますが、「逃走より早く動く技も欲しい」なんてケースを考えて調整するのも良いかと思います。
行動の処理
StartActions()では主にフラグの管理とコルーチンの起動を行なっています。デバッグ用に計算された優先度でコンソールに行動順を出力するようにしています。
ProcessAction()のコルーチンでは優先度の大きい方から順番に並べ替えて処理を進めていきます。もし「BattleManager」側で戦闘終了の状態になっていたらコルーチンを終了させます。このフラグはまだ「BattleManager」に用意していないので、後ほど追加しましょう。
コマンドに応じた分岐は、現時点では何も入れていませんが、各行動を処理するクラスを実装した後に分岐に対応させるように記載します。行動が完了した後、プロセスのポーズフラグがtrueの間は次の行動に進まずに処理を一旦停止し、falseになったら次に進むようにします。
StopActions()では、敵を倒した後などにコルーチンを止められるようにします。上記のコルーチン内でもフラグを検知して止まるようにはしていますが、処理の段階によっては続きの処理に進む可能性もあるため、外部から止められるようにしておきます。
便利クラス
キャラクターのパラメータや名前を取得するメソッドも用意しておきます。引数のフラグに応じて、敵または味方の情報を取得します。これらのメソッドは各行動を管理するクラスから呼び出して使用したいと思います。
フラグの制御
それぞれのフラグを制御するメソッドです。ShowNextMessage()のメソッドは「BattleManager」から呼び出される想定です。というのも、「MessageWindowController」でメッセージ表示が終わったら「BattleManager」に通知するためです。戦闘のフェーズが行動フェーズの場合は、今回作成中の「BattleActionProcessor」に通知してもらうようにしましょう。
ShowNextMessage()のメソッドからはSetPauseMessage()のメソッドを呼び出します。メッセージのポーズ状態を切り替えることで、各行動内で待ち合わせしていたのが完了して次に進むようにしたいと思います。
SetPauseProcess()のメソッドでは行動プロセスのポーズ状態を切り替えます。こちらは主に各行動の処理クラスから呼び出して切り替えるようにします。行動によって完了のポイントが異なるので、呼び出すタイミングは各行動の処理クラス側で制御します。
デバッグ用の処理
こちらはデバッグ用のメソッドで、データ上の行動順をコンソールに出力するようにしています。こちらの値と、画面での行動順を擦り合わせて意図しない順番になっていないか検知できるようにしました。
既存のクラスの修正
今回実装した機能と繋ぎ合わせるため、既存のクラスも修正していきます。対象は、
- BattleManager
です。
BattleManagerの修正
「BattleManager」では
- 「BattleActionProcessor」への参照用フィールドの追加
- 戦闘中かどうかのフラグのフィールドを追加
- 初期化処理の追加
- コマンド入力時の行動初期化処理の追加
- メッセージのコールバック用メソッドへの分岐の追加
- ターン内の行動が終了した際のコールバック用メソッドの追加
を行います。
前回追加した「_battleActionRegister」の下に「BattleActionProcessor」への参照用フィールドを追加しています。
また、ターン数のフィールドの下に「IsBattleFinished」のフィールドを追加しています。
StartBattle()のメソッドでは、以前追加した「_enemyCommandSelector」の初期化処理の上2行に行動に関する初期化処理を入れています。「_battleActionRegister」に対して「BattleActionProcessor」の参照を渡せるようになったので、こちらも追加しました。
コマンド入力フェーズに移行する際に、前のターンの行動が残っていると問題になるため、StartInputCommandPhase()のメソッド内で行動リストの初期化処理を呼ぶようにしました。
既存のOnFinishedShowMessage()のメソッドでは、戦闘のフェーズが行動の時の分岐を追加しました。行動フェーズでメッセージの表示が完了したら、「BattleActionProcessor」に通知を行うようにしています。
また、「BattleActionProcessor」でのターン内の行動が終了した際には、OnFinishedActions()を呼ぶようにしています。ターン内の行動が終了して、かつ戦闘が終わっていない場合は、ターン数のカウントを増やしてコマンド入力のフェーズに戻ります。決着が着くまでこの繰り返しが行われることになります。
参照のアサイン
スクリプトを保存したら、必要な参照をアサインしていきましょう。Hierarchyウィンドウから「BattleManager」のゲームオブジェクトを選択し、Inspectorウィンドウから今回フィールドを追加した「BattleActionProcessor」への参照をアサインしましょう。

動作確認
今回も戦闘を開始してエラーがないことだけ確かめておきましょう。
今回のブランチ
まとめ
今回は行動選択を行うクラスを実装しました。個別の処理を別クラスに任せる予定とはいえ、全体の進行制御の部分は処理が多くなりますね。
次回は各行動を処理するクラスのうち、攻撃の行動を処理するクラスを実装していきます。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】RPGを作るチュートリアルその52 敵キャラクターの行動選択を行うクラス 2025.03.26
-
次の記事
【Unity】RPGを作るチュートリアルその54 攻撃に関する行動を処理するクラス 2025.03.28
コメントを書く