はじめに
Unityでキャラクター制御やAIを作っていると、最初はシンプルだったはずのコードが、気づけば if文やswitch文だらけ になっていませんか?
「ジャンプ中は攻撃できない」「ダメージ中は移動させたくない」
そんな条件を足していくうちに、フラグが増え、分岐が増え、
どこを直せばいいのか分からないコードになってしまう……。
私自身も、Unityを触り始めた頃は「とりあえずifで分岐すれば動くからOK」と思っていました。
でも、アクションやAIが少し複雑になった瞬間、その書き方が一気に限界を迎えます。
そんなときに役立つのが、ステートマシン(State Machine / FSM)という考え方です。
ステートマシンを使うと、
- 「今キャラがどんな状態なのか」が明確になる
- 状態ごとの処理を整理できる
- あとから機能を追加しても壊れにくくなる
といったメリットがあり、プレイヤー制御・敵AI・ゲーム全体の状態管理まで、幅広く応用できます。
ただし、いきなり難しい設計を目指す必要はありません。
ECSやDIのような大規模アーキテクチャに進む前に、「今の書き方を一段よくする」選択肢としてFSMはとてもちょうどいい存在です。
この記事では、
- ステートマシン(FSM)とは何か
- Unityでよくある状態管理の失敗例
- enumから始めるシンプルなFSM実装
- クラス分割による実践的な設計
- 「どこまでFSMを使うべきか」の判断基準
といった内容を、初心者〜中級者の方でもイメージしやすいように解説していきます。
「今のコード、そろそろ限界かも……」と感じているなら、
ぜひこの先を読み進めてみてください 🙂
結論
先に結論からお伝えします。
Unityでの状態管理において、ステートマシン(FSM)は「if文の代替テクニック」ではなく、「設計を安定させるための考え方」です。
- 状態が排他的(同時に1つだけ成り立つ)な処理はFSMと相性がいい
- いきなり難しい実装をせず、enum+switchから始めるのが安全
- 処理が育ってきたら、Stateクラス分割に進むと破綻しにくい
逆に言うと、すべてをFSMで管理しようとするのはNGです。
状態がほとんど増えない処理や、一時的な条件分岐までFSMにしてしまうと、
コードはきれいになるどころか、むしろ分かりづらくなってしまいます。
大切なのは、
- 「この処理は本当に“状態”なのか?」
- 「将来、状態や分岐が増えそうか?」
を考えながら、必要なところにだけFSMを使うことです。
この記事ではこのあと、
- そもそもステートマシンとは何なのか
- なぜif文管理が破綻しやすいのか
- Unityでの現実的なFSM実装ステップ
を順番に見ていきます。

「FSMが自分のプロジェクトに合うのかどうか」を判断できるようになることを、
この記事のゴールにして読み進めてもらえるとうれしいです。
ステートマシン(FSM)とは何か【基礎理解】
FSMの基本構造(状態・遷移・入力)
ステートマシン(Finite State Machine / FSM)は、
「今どんな状態か」を1つだけ持ち、その状態が条件によって切り替わるという考え方です。
ポイントは、「同時に複数の状態を持たない」こと。
キャラクターは今この瞬間、必ず1つの状態にいるという前提で設計します。
FSMは、次の3つの要素で構成されます。
- 状態(State):今何をしているか(待機・移動・攻撃など)
- 遷移(Transition):別の状態へ切り替わるルール
- 入力・イベント(Input / Event):遷移のきっかけ(キー入力・衝突・時間経過など)
たとえばプレイヤーキャラなら、
- 待機状態で移動キーが押された → 移動状態へ
- 移動中にジャンプボタンが押された → ジャンプ状態へ
- 着地した → 待機状態へ
というように、状態と状態のつながりとして挙動を考えます。
なぜゲーム開発と相性がいいのか
ゲームの処理は、よく考えると「状態の集合体」です。
プレイヤー、敵AI、UI、ゲーム進行など、ほとんどの要素が
「今は〇〇中」「次は△△になる」という形で動いています。
ところが、これをそのまま if 文で書き始めると、
- 状態の組み合わせをすべて条件で表現する必要がある
- どの条件がどの挙動に関係しているのか分かりにくい
- あとから追加した条件が、既存の挙動を壊しやすい
といった問題が起きやすくなります。
FSMを使うと、
- 「今はこの状態だから、この処理だけを考えればいい」
- 状態遷移の条件がはっきりする
- 関係ない状態のコードを触らずに済む
という形で、考える範囲を自然に絞れるのが大きなメリットです。

この「思考の整理」ができるようになると、
コード量以上に、修正や拡張のストレスが一気に減ります。
Unityでよくある「状態管理の破綻例」
ステートマシンの話に入る前に、
まずは Unityで本当によく見る「つらくなる状態管理」 を整理しておきましょう。
ここに心当たりがある人ほど、FSMの効果を実感しやすいはずです。
boolフラグが増え続ける「フラグ地獄」
初心者〜中級者の方がまず陥りやすいのが、
bool変数で状態を管理し始めてしまうパターンです。
bool isMoving;
bool isJumping;
bool isAttacking;
bool isDamaged;
最初は分かりやすいのですが、処理が増えてくると、
- ジャンプ中は攻撃できる?できない?
- ダメージ中に移動入力が来たらどうする?
- 複数のboolが同時にtrueになっていいの?
といった 状態の組み合わせ問題 が一気に押し寄せます。
結果として、
- ありえない状態が同時に成立する
- 特定の操作だけバグる
- 修正するたびに別の場所が壊れる
という、かなり危険な状態になりがちです。
この問題をもう少し掘り下げたい方は、
こちらの記事も参考になります。
switch文が肥大化していくパターン
「boolは危ないと聞いたから」と、次に選ばれやすいのが
enum+switch文での状態管理です。
これは方向性としては正しく、実際かなり改善されます。
ただし、状態が増えてくると、こんな問題が出てきます。
- switch文が1ファイルに集中して巨大化する
- 状態ごとの処理が長くなり、見通しが悪くなる
- 「この状態だけ特別な変数」が増えていく
結果として、
「状態は整理されているはずなのに、修正が怖い」
という、別の形のストレスが生まれます。
ここまで来ると、
- 状態ごとの責務を分けたい
- 関係ない状態のコードを触りたくない
と感じ始めるはずです。

この「違和感」こそが、
FSMを 次の段階(クラス分割)へ進める合図 になります。
FSMの実装パターン①:enum + switch(最初の一歩)
ここまでで、「bool管理はつらい」「if文が増えると壊れやすい」という感覚が なんとなく見えてきたと思います。
そこでまず試してほしいのが、enum と switch 文を使ったシンプルなFSMです。
これはいきなり難しい設計に進むのではなく、
考え方だけFSMに寄せるための、とても安全なステップになります。
enumで「状態」を一意にする
まずは状態を enum で定義します。
public enum PlayerState
{
Idle,
Move,
Jump,
Attack
}
そして、現在の状態を1つだけ持つようにします。
PlayerState currentState = PlayerState.Idle;
この時点で、
「ジャンプ中かつ待機中」のような矛盾状態は 構造的に起こらなくなります。
Updateで状態ごとの処理を分岐する
次に、Updateなどで状態ごとの処理を書きます。
void Update()
{
switch (currentState)
{
case PlayerState.Idle:
UpdateIdle();
break;
case PlayerState.Move:
UpdateMove();
break;
case PlayerState.Jump:
UpdateJump();
break;
case PlayerState.Attack:
UpdateAttack();
break;
}
}
処理をメソッドに分けるだけでも、
- 今どの状態の処理を書いているかが分かりやすい
- 状態ごとにロジックを整理できる
といった効果があります。
enum FSMのメリットと限界
この方法のメリットは、とても分かりやすいことです。
- FSMの考え方をコードで体感できる
- 既存コードから移行しやすい
- 小規模なら十分実用的
一方で、プロジェクトが育ってくると、限界も見えてきます。
- switch文がどんどん長くなる
- 状態専用の変数がクラスに溜まっていく
- 状態ごとの責務が完全には分離できない
つまり、
「状態は整理できたけど、クラス自体はまだ重たい」
という状態です。
この段階まで来たら、
FSMを 「設計として完成させる」 方法に進む価値があります。

次の章では、
状態そのものをクラスとして分離するFSM(Stateパターン)を見ていきましょう。
FSMの実装パターン②:Stateパターン(クラス分割)
enum+switch のFSMで「考え方」はかなり整理されましたが、
次に出てくるのが 「1つのクラスが重たくなってきた問題」 です。
ここで登場するのが、StateパターンによるFSM(クラス分割FSM)です。
この方法では、
「状態=処理のまとまり」そのものをクラスとして分離します。
クラス分割FSMの基本構造
まず、すべての状態が共通で持つインターフェース(または基底クラス)を用意します。
public interface IPlayerState
{
void Enter();
void Update();
void Exit();
}
次に、それぞれの状態をクラスとして実装します。
public class IdleState : IPlayerState
{
public void Enter()
{
// 待機状態に入ったときの処理
}
public void Update()
{
// 待機中の処理
}
public void Exit()
{
// 待機状態を抜けるときの処理
}
}
ジャンプ・攻撃・移動も同じようにクラスを分けていきます。
状態を管理する「コンテキスト」クラス
状態を切り替える役割を持つのが、いわゆる コンテキスト です。
public class PlayerStateMachine
{
IPlayerState currentState;
public void ChangeState(IPlayerState newState)
{
currentState?.Exit();
currentState = newState;
currentState.Enter();
}
public void Update()
{
currentState?.Update();
}
}
ここで重要なのは、
- 状態遷移の責務が一か所に集まる
- 各Stateクラスは「自分の状態」だけを考えればいい
という点です。
enum FSMと比べて、
- 関係ない状態のコードを一切触らずに済む
- 状態ごとの処理が自然に分離される
- ファイル単位で見通しがよくなる
といったメリットがあります。
実装イメージを一気に掴みたい人向け
「仕組みは分かったけど、
実際のプロジェクトでどう組まれているか見てみたい」
そんな方には、FSM設計の実例として、
完成度の高いテンプレートを見るのもかなり勉強になります。
この手のアセットは、
- いきなり導入して使う
- 仕組みを理解せずにブラックボックス化する
よりも、
FSMを自分で一度書いたあとに「答え合わせ」として見るのがおすすめです。

「なるほど、こう分けるのか」という発見が必ずあります。
Animator・AI・GameStateへの応用例
ここまでで、FSMの基本構造と実装イメージはつかめてきたと思います。
実はステートマシンは、
プレイヤー制御だけのテクニックではありません。
Unityではすでに、
FSMの考え方がいろいろな場所で使われています。
Animatorは「ビジュアルなステートマシン」
UnityのAnimator(Mecanim)は、
FSMを視覚的に扱える仕組みそのものです。
アニメーションクリップが「状態」、
遷移条件(bool / trigger / float)が「遷移ルール」に相当します。
さらに StateMachineBehaviour を使えば、
- 状態に入った瞬間の処理
- 状態中の更新処理
- 状態を抜けたときの処理
をコード側で分離できます。
これは、
先ほど紹介した Stateパターンとほぼ同じ発想です。
Animatorを使っていて「遷移が分からなくなってきた」と感じたら、
それはFSM設計を見直すサインでもあります。
敵AIへの応用(FSMとビヘイビアツリー)
敵AIは、FSMが最もよく使われる分野のひとつです。
- 待機
- 索敵
- 追跡
- 攻撃
といった行動は、
状態として非常にきれいに分けられます。
ただし、行動条件が複雑になってくると、
FSMだけでは管理がつらくなるケースもあります。
その場合によく使われるのが、
ビヘイビアツリー(Behavior Tree)です。
FSMとビヘイビアツリーの使い分けについては、
こちらの記事で詳しく解説しています。
実装を効率化したい場合は、
実績のあるツールを使うのも1つの選択肢です。
Behavior Designer(Behavior Tree)
GameState管理への応用
FSMは、
ゲーム全体の状態管理(GameState)にも非常に向いています。
- タイトル
- プレイ中
- ポーズ
- リザルト
これらはすべて、
「今ゲームがどの状態にあるか」という排他的な状態です。
GameStateをFSMで管理すると、
- 入力の有効・無効
- UIの表示切り替え
- Time.timeScaleの制御
を 状態単位でまとめて制御できます。
GameState設計については、
以下の記事でより踏み込んだ解説をしています。
「どこまでFSMを使うべきか」の判断基準
FSMはとても便利ですが、
「使えば使うほど良くなる万能設計」ではありません。
ここを見誤ると、
- 設計が過剰に複雑になる
- 読むだけで疲れるコードになる
- 修正コストが逆に上がる
という本末転倒な状態になってしまいます。
この章では、
FSMを使うべきケース/使わなくていいケースを整理します。
FSMが向いているケース
次の条件に当てはまる処理は、FSMと非常に相性がいいです。
- 状態が排他的(同時に1つだけ成り立つ)
- 状態の数が今後増えそう
- 状態ごとに振る舞いが大きく変わる
- バグが出ると修正コストが高い
典型例としては、
- プレイヤーの行動状態
- 敵AIの行動フェーズ
- ゲーム全体の進行状態(GameState)
などがあります。
これらは後から仕様変更が入りやすく、
FSMで構造を固めておく価値が高い部分です。
FSMを使わなくていいケース
一方で、次のような処理はFSMにしないほうがシンプルです。
- 状態が2〜3個から増えない
- 一時的・瞬間的な条件分岐
- 単発イベントの制御
たとえば、
- ボタンを押した瞬間の処理
- 一度きりの演出
- フラグON/OFFで十分な制御
までFSMにしてしまうと、
「設計は立派だけど、読むのがつらいコード」
になりがちです。
並行ステートという考え方
FSMでよくある失敗が、
「全部を1つのFSMで管理しようとする」ことです。
たとえば、
- 移動状態(待機・移動・ジャンプ)
- 装備状態(素手・剣・弓)
これらは、
本来は独立した状態です。
無理に1つのFSMにまとめると、
状態数が爆発してしまいます。
こういう場合は、
- 移動用FSM
- 装備用FSM
のように、
複数のFSMを並行して動かすほうが安全です。
実装を効率化したい場合の選択肢
「判断基準は分かったけど、
毎回FSMを1から書くのは大変」
という場合は、
FSM専用の仕組みが用意されたツールを使うのも現実的です。
ただし、ここでも大切なのは、
「仕組みを理解した上で使う」ことです。

FSMの判断基準が分かっていれば、
ツールを使う/使わないの選択も、ずっと冷静にできるようになります。
よくある誤解・失敗例
ステートマシン(FSM)は便利な設計ですが、
導入の仕方を間違えると、かえってコードを分かりにくくしてしまうことがあります。
ここでは、実際によく見かける誤解・失敗パターンを整理しておきます。
FSM=難しい設計だと思い込んでしまう
「FSMって設計パターンでしょ?難しそう……」
こう感じてしまい、最初から避けてしまう人は意外と多いです。
でも実際は、
- enumで状態を1つにまとめる
- 状態ごとに処理を分けて考える
この時点ですでにFSMの考え方は始まっています。
いきなりクラス分割までやる必要はありません。
「状態を意識する」だけでも、設計は確実に改善します。
すべてをFSMで管理しようとしてしまう
FSMを知った直後にやりがちなのが、
「この処理もFSMで管理しよう」と何でも当てはめてしまうことです。
結果として、
- 状態の数が必要以上に増える
- 状態遷移が追えなくなる
- 単純な処理が逆に分かりにくくなる
という状況に陥ります。
FSMは「状態が排他的に切り替わる処理」に使うもの。
一時的なフラグ制御や単発イベントまでFSMにする必要はありません。
責務分離ができていないままクラス分割する
Stateパターンを導入したものの、
- Stateクラスが巨大になっている
- 他のStateの処理に直接触っている
というケースもよく見かけます。
これは、
「状態ごとに責務を分ける」という意識が弱いままクラス分割したことが原因です。
FSMは、状態を分けること自体が目的ではなく、
「変更の影響範囲を狭くする」ための設計です。
責務分離の考え方がまだ曖昧な場合は、
こちらの記事もあわせて読むと理解が深まります。
まとめ
この記事では、Unityにおけるステートマシン(FSM)の考え方と、
現実的な導入ステップについて解説してきました。
- if文やbool管理は、規模が大きくなると破綻しやすい
- FSMは「状態」を軸に処理を整理する設計手法
- enum+switchから始めて、必要に応じてクラス分割へ進む
- すべてをFSMにせず、使いどころを見極めることが大切
FSMは、
コードを賢く見せるためのテクニックではありません。
「あとから直しやすいか」「仕様変更に耐えられるか」
そのための土台を作る設計です。
今のコードに少しでも違和感を感じているなら、
まずは enum で状態をまとめるところから、ぜひ試してみてください。
きっと、修正や拡張が前よりずっと楽になるはずです 🙂
参考文献・参考リンク
- Finite-state machine – Wikipedia
- State – Game Programming Patterns
- State Pattern – Refactoring.Guru
- Finite-State Machines to the Rescue – Game Programming Patterns
- Level up your code with game programming patterns – Unity Blog
- State Machines Explained – GameDev.net
- Animation State Machines – Unity Manual
- State Pattern Using Unity – raywenderlich.com
- The State Pattern – Game Programming Patterns
- Clean code & architecture for Unity – Unity Blog
- Behavioral Patterns – Game Programming Patterns
- When to Use the State Pattern – Game Programming Patterns
- Separation of Concerns – Wikipedia
- Behavior Tree – Wikipedia
- Behavior Trees for AI: How They Work – Game Developer
よくある質問(FAQ)
- QFSMとStateパターンは同じものですか?
- A
考え方は近いですが、完全に同じではありません。
FSMは「状態と遷移のモデル」、Stateパターンはそれをオブジェクト指向で実装するための設計パターンです。
- QAnimatorだけ使っていればFSMは不要ですか?
- A
アニメーション制御だけならAnimatorで十分な場合も多いです。
ただし、入力制御・AI・GameStateなど、アニメーション以外の状態管理にはFSMの考え方が役立ちます。
- QECSやDIに進む前にFSMは学ぶべきですか?
- A
個人的には「はい」です。
FSMで状態と責務を整理できるようになると、ECSやDIの考え方も理解しやすくなります。











※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。