【Unity】Unityでコマンドデザインパターンを当てはめてみる

Unityにおけるコマンドパターンは、ゲーム開発においてよく使用されるデザインパターンの一つです。コマンドパターンは、特定のアクションをカプセル化し、それを後で実行したり元に戻したりするための柔軟な方法を提供します。

以下に、Unityでコマンドパターンを実装する一般的な手順を示します。

  1. コマンドインターフェースの作成: 最初に、コマンドの基本的な操作を定義するためのインターフェースを作成します。例えば、ICommandという名前のインターフェースを作成することができます。このインターフェースには、Execute()Undo()のようなメソッドが含まれるでしょう。
  2. コマンドクラスの作成: 次に、具体的なコマンドの実装クラスを作成します。各コマンドは、ICommandインターフェースを実装し、Execute()メソッドとUndo()メソッドを実装します。例えば、JumpCommandAttackCommandなどの具体的なコマンドクラスを作成することができます。
  3. コマンドの実行: コマンドを実行するオブジェクトを作成します。このオブジェクトは、ICommandインターフェースを持つメンバ変数を持ち、そのメンバ変数に対して実行するコマンドをセットします。実行するアクションが発生した場合には、セットされたコマンドのExecute()メソッドを呼び出します。
  4. コマンドの管理: コマンドの履歴や連鎖的なコマンドの管理が必要な場合は、それに対応するデータ構造やロジックを実装する必要があります。例えば、スタックを使用してコマンドの履歴を管理することができます。

コマンドパターンを使用することで、特定のアクションを実行するオブジェクトとそのアクション自体を分離することができます。これにより、アクションの履歴を追跡したり、アクションの取り消しややり直しを実装したりすることが容易になります。また、複雑なアクションの組み合わせや連鎖を管理する際にも役立ちます。

ただし、Unityでは、コマンドパターンを使用する必要性や適切さは、具体的なゲームの要件やアーキテクチャに依存します。プロジェクトの要件と開発チームの好みに基づいて、デザインパターンを適用するかどうかを検討することが重要です。

サンプル

以下は、Unityでコマンドパターンを実装する簡単な例です。この例では、プレイヤーがジャンプするアクションをコマンドとして扱います。

// ICommand インターフェース
public interface ICommand
{
    void Execute();
    void Undo();
}

// ジャンプコマンドクラス
public class JumpCommand : ICommand
{
    private Player player;

    public JumpCommand(Player player)
    {
        this.player = player;
    }

    public void Execute()
    {
        player.Jump();
    }

    public void Undo()
    {
        player.UndoJump();
    }
}

// プレイヤークラス
public class Player : MonoBehaviour
{
    private ICommand jumpCommand;

    public void Jump()
    {
        // ジャンプの処理
        Debug.Log("Jump!");

        // ジャンプを実行した場合、コマンドを保存する
        jumpCommand = new JumpCommand(this);
    }

    public void UndoJump()
    {
        // ジャンプの取り消し処理
        Debug.Log("Undo Jump!");
    }

    public void PerformJump()
    {
        // コマンドの実行
        if (jumpCommand != null)
        {
            jumpCommand.Execute();
        }
    }

    public void PerformUndoJump()
    {
        // コマンドの取り消し
        if (jumpCommand != null)
        {
            jumpCommand.Undo();
            jumpCommand = null;
        }
    }
}

// 使用例
public class Example : MonoBehaviour
{
    private Player player;

    private void Start()
    {
        player = new Player();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            player.PerformJump();
        }
        else if (Input.GetKeyDown(KeyCode.U))
        {
            player.PerformUndoJump();
        }
    }
}

この例では、ICommandインターフェースを定義し、JumpCommandクラスがそのインターフェースを実装しています。Playerクラスでは、ジャンプアクションを実行するJump()メソッドと取り消すUndoJump()メソッドがあります。Jump()メソッドが呼び出された際には、対応するJumpCommandオブジェクトが生成され、保存されます。その後、PerformJump()メソッドでコマンドが実行され、PerformUndoJump()メソッドでコマンドが取り消されます。

このようにコマンドパターンを使用すると、ゲーム内のアクションを柔軟に管理することができます。