コマンドパターン

コマンドパターン(Command Pattern)は、例えばゲーム内のアクション(キャラクターの移動、攻撃、ジャンプ、防御など)を

オブジェクトとして抽象化し、実行を柔軟に制御するためのデザインパターンです。

よくある、Undo/Redoの仕組みもこのコマンドパターンで実装されていることが多いと思います。

コマンドパターンのイメージ

コマンド用のインターフェイスを用意します。

public interface ICommand
{
	void Execute();
}

このインターフェイスを継承したコマンドを実装します。

public class AttackCommand : ICommand
{
	public void Execute()
	{
		// 攻撃
	}
}

public class MoveForwardCommand : ICommand
{
	public void Execute()
	{
		// 前進
	}
}

コマンドを登録して実行する為の以下のようなクラスを用意します。

public class CommandHandler
{
	private List<ICommand> _commands = new();
	
	// コマンドを登録する
	public void AddCommand(ICommand command)
	{
		_commands.Add(command);
	}
	
	// 先頭のコマンドを取り出して実行する
	public void Execute()
	{
		if(_commands.Count > 0)
		{
			var command = _commands[0];
			_commands.RemoveAt(0);
			
			command.Execute();
		}
	}
}

使い方の例

前段のコードを実際に使ってみると以下のようになります。

public class Player : MonoBehaviour
{
	private CommandHandler _commandHandler = new();

	private void Update()
	{
		if(Input.GetKeyDown(
[KeyCode.Space](http://keycode.space/)
))
		{
			// 攻撃コマンド登録
			_commandHandler.AddCommand(new AttackCommand());
		}
		if(Input.GetKeyDown(KeyCode.W))
		{
			// 前進コマンド登録
			_commandHandler.AddCommand(new MoveForwardCommand());
		}
		
		// コマンド実行
		_commandHandler.Execute();
	}
}

キー入力のif文の後に動作の実装をせず、コマンドクラスに全部任せています。

今回は最小限ですが、各コマンドにコマンドの対象となるオブジェクトを登録させればコマンドに応じた動作を実行させています。

  • アニメーションを再生する
  • サウンドを再生する
  • 移動させる

など。

このサンプルではListにコマンドを登録していますが、必ず先頭から取り出すならQueueを使うことも出来ます。

Undoを実装したい場合は、Stackにコマンドを登録するのがよいでしょう。

この辺りは必要に応じてアレンジ出来ます。

使いどころ

Undo/Redo

Unityエディタやテキストエディタなどにも実装されていますが、

各処理をコマンド化することでUndo/Redoに使用できます。

シミュレーションゲームなどで建物を設置したりやり直したりするのにも使えそうです。

入力の再現

チュートリアルシーンなどでキャラクターを動かしたい場合に、

事前に入力情報をコマンドとして保存しておき、

それを元にコマンドを実行していけば入力を再現出来ます。

バトル中の演出を事前に登録しておく

コマンドバトルなどでプレイヤー側が行動を選択した後、

バトル中に起きる出来事を全てコマンドとして登録しておけば、

後は順に再生するだけになります。

注意点

無制限でコマンドを登録出来ると、メモリを圧迫する可能性が出てきます。

特にUndoに使用する場合は、ある程度で履歴の制限を設けた方が良いでしょう。

まとめ

今回はデザインパターンのコマンドパターンについて簡単に解説しました。

入力などで発生する処理をコマンドとしてオブジェクト化しておくことで、

UIやキー入力時はコマンドを発行するだけになり、実行する側もただ順にコマンドを実行するだけになります。

コマンドパターンを使うことでUndo/Redoの実装や、コマンドの再現などを実現出来ます。

ゲーム中の入力を保存しておいてリプレイシーンに利用したり、

ネットワーク対戦ゲームで入力をコマンド化して相手に送り相手の環境で再現することも出来るかもしれません。

ゲームとは相性がいいので活用してみてください。

📣おしらせ!

Unity Asset Storeで GROW YOUR GARDEN セール が開催中です。

農業関係のアセットなどが最大50%OFFでセール中です。

🔗関連ページ