命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成对象,从而使得可以使用不同的请求、队列或日志请求,以及支持可撤销的操作。命令模式通常包含四个主要角色:命令(Command)、接收者(Receiver)、请求者(Invoker)和客户端(Client)。命令对象持有请求的详细信息,而接收者则执行这些请求。
什么时候使用命令模式
- 需要支持撤销/重做功能时:例如文本编辑器、绘图软件等需要频繁撤销和重做操作的应用。
- 需要将请求发送者与接收者解耦时:当请求的发送者和接收者之间的依赖关系需要降低时,可以使用命令模式。
- 需要记录请求日志时:当需要跟踪请求的历史以进行审计时,命令模式提供了一种优雅的解决方案。
- 需要实现异步请求时:可以将请求放入队列中,并在未来的某个时间点执行。
在 Unity 中使用 命令模式
在 Unity 中实现 命令模式 的示例,我们可以创建一个简单的场景,其中玩家可以使用命令来控制一个角色的移动和跳跃。这个示例将演示如何使用命令模式来处理这些操作。
1、定义命令接口
首先,我们定义一个命令接口,描述执行命令的基本操作。
cs
public interface ICommand
{
void Execute();
void Undo();
}
2、定义接收者类
接下来,我们定义一个接收者类,代表要执行命令的对象(如角色)。
cs
using UnityEngine;
public class PlayerCharacter : MonoBehaviour
{
public void Move(Vector3 direction)
{
transform.position += direction;
Debug.Log($"Moved to: {transform.position}");
}
public void Jump(float height)
{
transform.position += Vector3.up * height;
Debug.Log($"Jumped to: {transform.position}");
}
}
3、实现具体命令类
然后,我们实现具体的命令类,分别用于角色的移动和跳跃操作。
cs
public class MoveCommand : ICommand
{
private PlayerCharacter player;
private Vector3 direction;
public MoveCommand(PlayerCharacter player, Vector3 direction)
{
this.player = player;
this.direction = direction;
}
public void Execute()
{
player.Move(direction);
}
public void Undo()
{
player.Move(-direction); // 反向移动
}
}
public class JumpCommand : ICommand
{
private PlayerCharacter player;
private float height;
public JumpCommand(PlayerCharacter player, float height)
{
this.player = player;
this.height = height;
}
public void Execute()
{
player.Jump(height);
}
public void Undo()
{
player.Move(-Vector3.up * height); // 反向跳跃
}
}
4、实现请求者类
我们实现一个请求者类,用于调用命令。
cs
using System.Collections.Generic;
using UnityEngine;
public class CommandInvoker : MonoBehaviour
{
private Stack<ICommand> commandHistory = new Stack<ICommand>();
public void ExecuteCommand(ICommand command)
{
command.Execute();
commandHistory.Push(command);
}
public void UndoCommand()
{
if (commandHistory.Count > 0)
{
ICommand lastCommand = commandHistory.Pop();
lastCommand.Undo();
}
}
}
5、创建游戏管理器
最后,我们创建一个游戏管理器类,处理用户输入并执行命令。
cs
using UnityEngine;
public class GameManager : MonoBehaviour
{
public PlayerCharacter playerCharacter;
private CommandInvoker commandInvoker;
void Start()
{
commandInvoker = gameObject.AddComponent<CommandInvoker>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
var moveCommand = new MoveCommand(playerCharacter, Vector3.forward);
commandInvoker.ExecuteCommand(moveCommand);
}
else if (Input.GetKeyDown(KeyCode.S))
{
var moveCommand = new MoveCommand(playerCharacter, Vector3.back);
commandInvoker.ExecuteCommand(moveCommand);
}
else if (Input.GetKeyDown(KeyCode.Space))
{
var jumpCommand = new JumpCommand(playerCharacter, 2.0f);
commandInvoker.ExecuteCommand(jumpCommand);
}
else if (Input.GetKeyDown(KeyCode.U))
{
commandInvoker.UndoCommand(); // 撤销上一个命令
}
}
}
6、在 Unity 中测试
- 创建一个带有 Collider 的 Cube 作为玩家角色,并附加 PlayerCharacter 脚本。
- 创建一个空的 GameObject,命名为 GameManager,并附加 GameManager 脚本。
- 运行游戏,使用 W 和 S 键控制前后移动,使用 Space 键跳跃,使用 U 键撤销上一个命令。
7、示例分析
- 命令(ICommand):定义执行和撤销的基本操作。
- 接收者(PlayerCharacter):实现角色的具体操作。
- 具体命令(MoveCommand 和 JumpCommand):封装角色的移动和跳跃逻辑。
- 请求者(CommandInvoker):负责执行和撤销命令。
这个示例展示了如何在 Unity 中实现 命令模式,通过封装角色的操作为命令对象,使得用户能够灵活地控制角色,同时支持撤销操作。这种模式在需要记录和管理用户输入的场景中非常有用。
今天是2024年12月4日
重复一段毒鸡汤来勉励我和你
你的对手在看书
你的仇人在磨刀
你的闺蜜在减肥
隔壁的老王在练腰
而你在干嘛?