在 Unity 开发中, 命令模式(Command Pattern)的核心是将”请求”封装成独立的命令对象, 解耦请求”发送者”(如玩家输入\AI指令)和”接收者”(如角色\道具). 命令对象可以被存储\传递\撤销或重做, 还能支持批量执行(宏命令), 非常适合需要灵活控制操作流程的场景.
 

举个具体场景: 角色操作与撤销系统

假设你在开发一款2D平台游戏, 角色需要支持一下操作:
  • 向做移动\向右移动
  • 跳跃
  • 攻击
 
传统写法会直接在输入管理器中调用角色的 \ 等方法, 导致输入逻辑和角色动作强耦合 ——— 如果后续要加”赊销上一步操作”(比如误触移动, 撤销回原来的位置)\”录制宏命令”(连续按3个键自动回放), 就需要大幅修改代码.
 
命令模式的解决思路: 把每个操作(移动\跳跃)封装成独立的”命令对象”, 输入管理器(发送者)只需”执行命令”, 角色(接收者)只需”响应命令”, 命令对象本身记录”执行/撤销”所需的状态(如移动前的位置).
 

命令模式的核心角色

  1. 抽象命令(Command): 定义命令的统一接口, 包含 Execute() (执行命令)和 Undo() (撤销命令)方法.
  1. 具体命令(Concrete Command): 实现抽象命令, 持有”接收者”引用, 封装具体的请求逻辑(如调用者角色的移动方法), 并记录撤销所需的状态(如移动前的位置).
  1. 接收者(Receiver): 执行命令对应的实际操作(如角色的移动\跳跃逻辑), 不知道命令的存在, 只专注于自身功能.
  1. 调用者(Invoker): 触发命令执行的对象(如输入管理器), 负责创建命令\调用 Execute() , 还能管理命令历史(用于撤销/重做).
  1. 客户端(Client): 组装命令\接收者和调用者, 定义命令的执行流程(如绑定输入到命令)
 

代码实现步骤

  1. 定义接收者(角色, 执行实际行动)
先实现角色的核心功能(移动\跳跃\攻击), 它是命令的”执行者”, 不关心命令的逻辑:
 
  1. 定义抽象命令接口
所有具体命令都要实现这个接口, 统一”执行”和”撤销”的行为:
 
  1. 实现具体命令 (封装每个操作)
每个操作对应一个具体命令, 持有 PlayerController (接收者)的引用, 实现 Execute()Undo() :
 
  1. 实现调用者(输入管理器, 触发命令)
调用者负责监听输入\创建命令\执行命令, 还能管理命令历史栈(用于撤销/重做)
 
  1. 在Unity中配置与测试
    1. 创建角色: 新建 2D Sprite对象作为角色, 添加 Rigidbody2D (设置 Gravity Scale = 3, Freeze Rotation Z)\ BoxCollider2D , 再添加 PlayerController 脚本.
    2. 创建调用者: 新建空对象名为为 GameManager , 添加 InputManager 脚本, 将角色对象拖到 _player 字段
    3. 测试操作
        • 按 A/D:角色左右移动,命令入栈;
        • 按 Space:角色跳跃;
        • 按 J:角色攻击;
        • 按 Z:撤销上一步操作(移动会恢复位置,跳跃会恢复速度);
        • 按 R:自动执行 “右移→跳跃→攻击” 连招,3 秒后自动撤销。
 

命令模式的核心优势

  1. 解耦发送者和接收者: InputManager (发送者)不需要知道 PlayerController (接收者) 的MoveLeft() \ Jump() 方法, 只需要调用命令的 Execute() , 后续修改角色动作或输入方式, 无需互相改动。
  1. 支持撤销 / 重做: 通过命令历史栈, 轻松实现 “撤销上一步” “重做下一步”(只需再加一个 redoStack 存储撤销命令).
  1. 支持命令队列和宏命令: 可以批量执行多个命令(如连招\AI的一系列动作), 还能延迟执行(如定时触发命令).
  1. 扩展性强: 新增操作(如 “下蹲”) 只需新增 CrouchCommand 类, 无需修改 InputMnaagerPlayerController , 符合开放 - 封闭原则.
 

命令模式 vs 责任链模式

  • 命令模式: 封装请求为对象, 重点是 “请求的存储 \ 执行 \ 撤销”, 发送者明确知道要执行哪个命令(但不关心接受者如何执行).
  • 责任链模式: 请求沿链条传递, 重点是”找到能处理请求的接收者” 发送者不知道哪个接收者会处理.
 

在Unity中的其他应用场景

  • AI行为树: AI的每个行为(如巡逻\ 攻击\ 逃跑)封装成命令, 通过行为树节点触发执行.
  • 技能系统: 技能的释放\ 冷却\ 效果触发封装成命令, 支持技能连招录制\ 延迟释放
  • 编译器工具: 自定义编辑器中的操作(如移动物体\删除资源) 封装成命令, 支持撤销/重做
 
总结: 命令模式就像”快递订单” ——— 你(发送者)下单(创建命令), 快递员(调用者)配送(执行命令), 商家(接收者)发货(实际动作). 订单本身可以被追踪(撤销)\批量处理(宏命令), 你不需要知道商家具体怎么发货, 只需要等待结果. 在Unity中, 它是实现灵活操作流程的”万能订单系统”