移動後行動システムは、SRPGの戦略性を高めます。
移動と行動を分離すれば、選択の幅が広がります。
この記事では、実装方法を詳しく解説します。
✨ この記事でわかること
- 行動状態の管理
- 移動後行動の実装
- 待機コマンドの実装
- 行動済みフラグの管理
- 実装例とコード

移動後行動システムは、行動状態から始めましょう。移動済み、行動済み、待機の3つの状態を管理します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
行動状態の管理

SRPGの戦略性は、「1ターンで何ができるか」をどう制御するかで大きく変わります。
その中心となるのが行動状態の管理です。
行動状態を管理しない場合、「何度でも移動できる」「攻撃後に再行動できる」など、意図しない挙動が発生しやすくなります。
そこで、ユニットが今どの段階にいるのかを明確にする必要があります。
ここでは、移動・行動・待機を整理するための基本的な行動状態システムを実装します。
行動状態システムの考え方
まずは、1ターン中のユニットの行動を段階的に分解します。
本記事では、以下の4つの状態を用意します。
|
1 2 3 4 5 6 7 8 9 |
using UnityEngine; public enum UnitActionState { Idle, // 待機中(まだ何もしていない) Moved, // 移動済み Acted, // 行動済み Completed // 完了(移動+行動、または待機) } |
このように状態を分けることで、「移動後に何ができるか」「行動後に何を禁止するか」をコード上で明確に制御できます。
行動状態を管理するクラス
次に、ユニットごとの行動状態を管理するクラスを作成します。
ターン開始時の初期化や、現在の状態取得・更新をここで一元管理します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public class ActionStateManager : MonoBehaviour { private Dictionary<Unit, UnitActionState> unitStates = new Dictionary<Unit, UnitActionState>(); public void InitializeTurn() { // ターン開始時に全ユニットを待機状態に foreach (var unit in GetAllUnits()) { unitStates[unit] = UnitActionState.Idle; } } public UnitActionState GetState(Unit unit) { if (!unitStates.ContainsKey(unit)) { unitStates[unit] = UnitActionState.Idle; } return unitStates[unit]; } public void SetState(Unit unit, UnitActionState state) { unitStates[unit] = state; } public bool CanMove(Unit unit) { UnitActionState state = GetState(unit); return state == UnitActionState.Idle || state == UnitActionState.Acted; } public bool CanAct(Unit unit) { UnitActionState state = GetState(unit); return state == UnitActionState.Idle || state == UnitActionState.Moved; } } |
このクラスを使うことで、「移動できるか」「行動できるか」を状態ベースで判定できます。
条件分岐が整理され、後から仕様を変更する場合も修正しやすくなります。
行動状態から生まれる行動パターン
行動状態を分けて管理すると、SRPGでおなじみの行動パターンを自然に表現できます。
基本となる行動パターンは次のとおりです。
- 移動のみ:位置取りを優先し、そのまま待機する
- 行動のみ:その場から攻撃やスキルを使用する
- 移動+行動:移動してから攻撃・支援を行う
- 待機:あえて何もせずターンを終了する
これらを自由に組み合わせられることで、「一歩下がって様子を見る」「移動だけして壁役になる」といったプレイヤーの判断が活きる戦術が可能になります。
行動状態の管理は、単なる内部処理ではありません。
プレイヤーに考える余地を与えるための設計そのものです。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
移動後行動の実装

移動後行動は、SRPGの戦略性を大きく高める仕組みです。
「移動して終わり」ではなく、移動した位置を見てから行動を選べることで、プレイヤーの判断がより重要になります。
例えば、敵の射程に入るかを確認してから攻撃する、一歩前に出て支援スキルを使う、といった柔軟な行動が可能になります。
ここでは、行動状態管理を利用して、移動 → 行動を自然につなげる仕組みを実装します。
移動後行動システムの考え方
移動後行動を実現するためには、「移動したかどうか」「行動したかどうか」を明確に区別する必要があります。
本システムでは、次のような流れで処理を行います。
- 移動前:
Idle - 移動後:
Moved - 行動後:
Completed
この状態遷移を守ることで、「移動後にだけ行動できる」「行動後はターン終了」といったSRPGらしい制御が可能になります。
移動と行動を制御するクラス
以下のクラスでは、移動処理と行動処理を分けて管理しつつ、行動状態に応じて次の状態へ遷移させています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
public class MoveThenActSystem : MonoBehaviour { public ActionStateManager stateManager; public MovementSystem movementSystem; public ActionSystem actionSystem; public void MoveUnit(Unit unit, Vector2Int targetPos) { if (!stateManager.CanMove(unit)) { return; } // 移動を実行 movementSystem.MoveUnit(unit, targetPos); // 状態を更新 UnitActionState currentState = stateManager.GetState(unit); if (currentState == UnitActionState.Idle) { stateManager.SetState(unit, UnitActionState.Moved); } else if (currentState == UnitActionState.Acted) { stateManager.SetState(unit, UnitActionState.Completed); } } public void ActAfterMove(Unit unit, ActionType actionType, Vector2Int targetPos) { if (!stateManager.CanAct(unit)) { return; } // 行動を実行 actionSystem.ExecuteAction(unit, actionType, targetPos); // 状態を更新 UnitActionState currentState = stateManager.GetState(unit); if (currentState == UnitActionState.Idle) { stateManager.SetState(unit, UnitActionState.Acted); } else if (currentState == UnitActionState.Moved) { stateManager.SetState(unit, UnitActionState.Completed); } } } |
このように、移動と行動のたびに状態を更新することで、「何が許可されていて、何が禁止されているのか」を明確にできます。
結果として、処理がシンプルになり、後から「移動後は攻撃のみ可能にしたい」「スキルは不可にしたい」といった仕様変更にも対応しやすくなります。

移動後行動の本質は「自由度」と「制御」の両立です。
状態を分けて管理することで、プレイヤーに考える余地を残しつつ、
ゲームバランスも保ちやすくなります。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
待機コマンドの実装

待機コマンドは、SRPGにおいて「何もしない」という選択肢を与える重要な仕組みです。
一見すると地味ですが、戦略性を成立させるために欠かせない要素です。
移動後行動が可能なシステムでは、「今は動かずにターンを終えたい」「移動だけして次の展開に備えたい」といった判断が頻繁に発生します。
ここでは、そうしたプレイヤーの判断を正しく処理するための待機コマンドの実装方法を解説します。
待機コマンドの役割
待機コマンドの役割はシンプルです。
そのユニットのターンを確実に終了させることにあります。
行動状態をCompletedに設定し、ターン終了処理を呼び出すことで、そのユニットが同一ターン内に再行動することを防ぎます。
これにより、「移動後に何もしない」「様子見をする」といったSRPGらしい判断が自然に成立します。
待機システムの実装
以下のクラスでは、待機コマンドを実行した際に、行動状態の更新とターン終了処理をまとめて行っています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class WaitSystem : MonoBehaviour { public ActionStateManager stateManager; public TurnSystem turnSystem; public void Wait(Unit unit) { // 状態を完了に stateManager.SetState(unit, UnitActionState.Completed); // ターンを終了 turnSystem.EndUnitTurn(unit); } public void WaitAfterMove(Unit unit) { // 移動済みの場合は完了に if (stateManager.GetState(unit) == UnitActionState.Moved) { stateManager.SetState(unit, UnitActionState.Completed); turnSystem.EndUnitTurn(unit); } } } |
Wait()は、行動前・行動後を問わず、即座にターンを終了させたい場合に使用します。
一方でWaitAfterMove()は、「移動したあとに待機する」ケースを想定したメソッドです。
待機が戦略性を生む理由
待機コマンドがあることで、プレイヤーは「最善手が存在しない状況」でも選択を迫られます。
あえて前に出ない、あえて攻撃しないという判断ができることで、陣形維持や敵の誘導といった間接的な戦術が可能になります。
待機は「何もしないコマンド」ではありません。次のターンを有利にするための行動として機能します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
行動済みフラグの管理

行動済みフラグは、「このターンに何をしたか」をシンプルに記録するための仕組みです。
行動状態管理と比べると地味ですが、処理の分岐を簡潔にしたい場面で非常に役立ちます。
特に、「移動したかどうか」「行動したかどうか」だけを判定したい場合、状態遷移よりもフラグ管理のほうが直感的に書けることがあります。
ここでは、移動済み・行動済みを個別に管理する行動済みフラグ管理システムを実装します。
行動済みフラグの考え方
行動済みフラグは、各ユニットに対して「移動したか」「行動したか」をtrue / falseで記録します。
この方法のメリットは、状態の組み合わせを意識せずに「もう移動できる?」「もう攻撃できる?」といった判定ができる点です。
フラグ管理システムの実装
以下のクラスでは、ユニットごとに移動済み・行動済みフラグを保持し、ターン中の行動可否を制御しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public class ActionFlagManager : MonoBehaviour { private Dictionary<Unit, bool> hasMoved = new Dictionary<Unit, bool>(); private Dictionary<Unit, bool> hasActed = new Dictionary<Unit, bool>(); public void ResetFlags(Unit unit) { hasMoved[unit] = false; hasActed[unit] = false; } public void SetMoved(Unit unit) { hasMoved[unit] = true; } public void SetActed(Unit unit) { hasActed[unit] = true; } public bool CanMove(Unit unit) { return !hasMoved.ContainsKey(unit) || !hasMoved[unit]; } public bool CanAct(Unit unit) { return !hasActed.ContainsKey(unit) || !hasActed[unit]; } public bool IsCompleted(Unit unit) { return (hasMoved.ContainsKey(unit) && hasMoved[unit]) || (hasActed.ContainsKey(unit) && hasActed[unit]); } } |
この実装では、フラグの有無によって行動可否を判断しています。複雑な状態遷移を意識しなくても、直感的に制御できるのが特徴です。
状態管理とフラグ管理の使い分け
行動状態管理と行動済みフラグ管理は、目的が少し異なります。
行動状態は「今どの段階にいるか」を表すのに向いており、フラグ管理は「すでに何をしたか」を判定するのに向いています。
シンプルなSRPGであればフラグ管理だけでも十分ですが、移動後行動や待機などの選択肢が増える場合は、状態管理と組み合わせて使うことで、より柔軟な設計が可能になります。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
実装例:完全な移動後行動システム

ここまでで、行動状態の管理・移動後行動・待機コマンド・行動済みフラグについて解説してきました。
このセクションでは、それらを1つのシステムとして統合した実装例を紹介します。
個別に見ると難しく感じる仕組みも、まとめて管理することで「SRPGらしい1ターンの流れ」が明確になります。
この実装例をベースにすれば、実際のゲーム制作にそのまま組み込むことも可能です。
統合システムの役割
このクラスの役割は、各システムを直接操作するのではなく、「ターンの流れ」と「プレイヤーの入力」を仲介することです。
ユニットが今どの行動を選んだのかに応じて、適切な処理を呼び出すことで、全体の制御をシンプルに保ちます。
完全な移動後行動システムの実装
以下が、行動状態・移動後行動・待機・フラグ管理を統合したクラスです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
using UnityEngine; public class CompleteMoveThenActSystem : MonoBehaviour { [Header("システム")] public ActionStateManager stateManager; public MoveThenActSystem moveActSystem; public WaitSystem waitSystem; public ActionFlagManager flagManager; public void OnTurnStart() { // 全ユニットの状態とフラグをリセット foreach (var unit in GetAllUnits()) { flagManager.ResetFlags(unit); stateManager.SetState(unit, UnitActionState.Idle); } } public void ProcessUnitAction(Unit unit, ActionCommand command) { switch (command.type) { case ActionType.Move: moveActSystem.MoveUnit(unit, command.targetPos); flagManager.SetMoved(unit); break; case ActionType.Attack: moveActSystem.ActAfterMove(unit, ActionType.Attack, command.targetPos); flagManager.SetActed(unit); break; case ActionType.Wait: waitSystem.Wait(unit); break; } } } |
OnTurnStart()では、ターン開始時にすべてのユニットを初期状態に戻します。
これにより、前ターンの行動が次のターンに影響することを防げます。
ProcessUnitAction()では、プレイヤーの選択に応じて「移動」「攻撃」「待機」を切り替えています。
この構成が実戦向きな理由
処理を役割ごとに分割し、最後に統合する構成にすることで、仕様変更に強いシステムになります。
例えば、
- 「移動後は攻撃だけ可能にしたい」
- 「特定のスキルは移動後に使えないようにしたい」
といった調整も、個別のシステムを修正するだけで対応できます。
このように、拡張しやすさと分かりやすさを両立しているのが、完全な移動後行動システムの大きなメリットです。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
よくある質問(FAQ)

Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
まとめ

移動後行動システムは、行動状態から始めましょう。
移動済み、行動済み、完了の状態を管理すれば、戦略性が高まります。
✅ 今日から始める3ステップ
- ステップ1:行動状態管理を実装する(所要2時間)
- ステップ2:移動後行動を実装する(所要2時間)
- ステップ3:待機コマンドを実装する(所要1時間)
本格的にUnityを学びたい方は、Unity入門の森で実践的なスキルを身につけましょう。
あなたのペースで、少しずつ進めていけば大丈夫です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる



コメント