【Unity】Unityでステートデザインパターンを当てはめてみる

Unityにおけるステートパターンは、ゲーム開発においてよく使用されるデザインパターンの一つです。ステートパターンは、オブジェクトの状態が変化する場合に使用され、それぞれの状態に関連する振る舞いをカプセル化します。

Unityでステートパターンを実装する際には、次の手順を通じて行うことが一般的です:

  1. ステート(状態)を表すクラスを作成します。各ステートは、共通のインターフェースや基底クラスを実装することがあります。
  2. 各ステートに関連する振る舞いや処理を実装します。たとえば、プレイヤーキャラクターの状態であれば、移動、攻撃、待機などの振る舞いを含めることができます。
  3. ステートマシン(状態遷移管理)クラスを作成します。このクラスは、現在の状態を管理し、適切な状態への遷移を処理します。
  4. ゲームオブジェクトやコンポーネントにステートマシンを組み込みます。ステートマシンは、ゲームオブジェクトの状態を制御し、遷移や振る舞いを実行します。

Unityには、ステートパターンを実装するためのさまざまな方法があります。たとえば、コルーチンやステートマシンフレームワーク(StateMachineBehaviour)を使用することができます。また、外部のステートマシンライブラリを導入することもできます。

ステートパターンを使用することで、ゲームオブジェクトの状態を明確に定義し、各状態に関連する処理を独立させることができます。これにより、柔軟でメンテナンス性の高いコードを実現し、ゲームの挙動やプレイヤーの操作を管理しやすくなります。

サンプル

以下に、Unityでステートパターンを実装するための簡単なサンプルコードを示します。この例では、プレイヤーキャラクターの状態を制御するステートマシンを作成します。

// ステートの基底クラス
public abstract class PlayerState
{
    public abstract void EnterState(PlayerController player);
    public abstract void UpdateState(PlayerController player);
    public abstract void ExitState(PlayerController player);
}

// 移動状態のクラス
public class MoveState : PlayerState
{
    public override void EnterState(PlayerController player)
    {
        // 移動処理の初期化など
    }

    public override void UpdateState(PlayerController player)
    {
        // 移動処理の更新など
    }

    public override void ExitState(PlayerController player)
    {
        // 移動処理の終了など
    }
}

// 攻撃状態のクラス
public class AttackState : PlayerState
{
    public override void EnterState(PlayerController player)
    {
        // 攻撃処理の初期化など
    }

    public override void UpdateState(PlayerController player)
    {
        // 攻撃処理の更新など
    }

    public override void ExitState(PlayerController player)
    {
        // 攻撃処理の終了など
    }
}

// プレイヤーコントローラークラス
public class PlayerController : MonoBehaviour
{
    private PlayerState currentState;

    private void Start()
    {
        // 最初の状態を設定
        currentState = new MoveState();
        currentState.EnterState(this);
    }

    private void Update()
    {
        // 現在の状態を更新
        currentState.UpdateState(this);

        // 状態遷移の判定などを行い、必要なら状態を変更
        if (Input.GetKeyDown(KeyCode.Space))
        {
            ChangeState(new AttackState());
        }
    }

    public void ChangeState(PlayerState newState)
    {
        // 現在の状態の終了処理を実行
        currentState.ExitState(this);

        // 新しい状態に切り替え
        currentState = newState;
        currentState.EnterState(this);
    }
}

このサンプルでは、PlayerStateクラスがステートの基底クラスとなり、各ステート(MoveStateAttackState)がそれを継承して実装されています。PlayerControllerクラスはステートマシンの役割を果たし、現在の状態の管理や状態の変更を行います。

プレイヤーコントローラーはStartメソッドで最初の状態を設定し、Updateメソッドで現在の状態を更新します。ChangeStateメソッドは、状態の変更を行う際に呼び出されます。

このようにステートパターンを実装することで、PlayerControllerクラスは状態ごとの振る舞いをカプセル化し、柔軟な状態遷移やプレイヤーキャラクターの制御が可能となります。ni