Unity 虚拟仿真实验中设计模式的使用 ——命令模式(Command Pattern)
📖 目录
前言
什么是命令模式
案例背景:虚拟仿真实验中的操作管理
案例效果图(示意)
代码实现
5.1 命令接口:ICommand
5.2 具体命令类:HeatCommand / CoolCommand
5.3 调用者:CommandInvoker
5.4 接收者:WaterHeater
5.5 UI 控制:按钮触发命令
运行流程
注意事项总结
扩展思考
总结
1. 前言
在虚拟仿真实验中,实验对象的操作可能需要:
记录操作顺序
撤销/重做操作
队列化操作执行
如果直接在 UI 里写逻辑,操作管理会混乱。
命令模式(Command Pattern) 可以把操作封装成对象,使得操作可 记录、撤销、排队,且 调用者与接收者解耦。
2. 什么是命令模式
命令模式:将一个请求封装成对象,从而使你可用不同的请求、队列化请求或记录请求日志,以及支持可撤销操作。
优点:
解耦调用者和接收者
可以记录、撤销或重做操作
易于扩展新操作
3. 案例背景:虚拟仿真实验中的操作管理
实验对象:水壶
可操作行为:
加热(HeatCommand)
冷却(CoolCommand)
UI 点击按钮 → 创建命令 → 执行
可以撤销操作 → 返回上一个状态
4. 案例效果图(示意)
[加热按钮] → HeatCommand → 水温升高
[冷却按钮] → CoolCommand → 水温下降
[撤销按钮] → 回到上一个状态
5. 代码实现
5.1 命令接口:ICommand
public interface ICommand
{void Execute();void Undo();
}
5.2 具体命令类
HeatCommand
using UnityEngine;public class HeatCommand : ICommand
{private WaterHeater receiver;private float previousTemp;public HeatCommand(WaterHeater receiver){this.receiver = receiver;}public void Execute(){previousTemp = receiver.Temperature;receiver.Heat();}public void Undo(){receiver.SetTemperature(previousTemp);}
}
CoolCommand
using UnityEngine;public class CoolCommand : ICommand
{private WaterHeater receiver;private float previousTemp;public CoolCommand(WaterHeater receiver){this.receiver = receiver;}public void Execute(){previousTemp = receiver.Temperature;receiver.Cool();}public void Undo(){receiver.SetTemperature(previousTemp);}
}
5.3 调用者:CommandInvoker
using System.Collections.Generic;public class CommandInvoker
{private Stack<ICommand> commandHistory = new Stack<ICommand>();public void ExecuteCommand(ICommand command){command.Execute();commandHistory.Push(command);}public void Undo(){if (commandHistory.Count > 0){ICommand command = commandHistory.Pop();command.Undo();}}
}
5.4 接收者:WaterHeater
using UnityEngine;public class WaterHeater : MonoBehaviour
{public float Temperature { get; private set; } = 20f;public void Heat(){Temperature += 10f;Debug.Log($"加热中,温度:{Temperature}℃");}public void Cool(){Temperature -= 10f;Debug.Log($"冷却中,温度:{Temperature}℃");}public void SetTemperature(float temp){Temperature = temp;Debug.Log($"撤销操作,温度恢复:{Temperature}℃");}
}
5.5 UI 控制:按钮触发命令
using UnityEngine;
using UnityEngine.UI;public class CommandUI : MonoBehaviour
{[SerializeField] private Button heatButton;[SerializeField] private Button coolButton;[SerializeField] private Button undoButton;[SerializeField] private WaterHeater waterHeater;private CommandInvoker invoker = new CommandInvoker();private void Start(){heatButton.onClick.AddListener(() =>{invoker.ExecuteCommand(new HeatCommand(waterHeater));});coolButton.onClick.AddListener(() =>{invoker.ExecuteCommand(new CoolCommand(waterHeater));});undoButton.onClick.AddListener(() =>{invoker.Undo();});}
}
6. 运行流程
玩家点击 加热按钮 → 创建 HeatCommand → 执行 → 温度升高
玩家点击 冷却按钮 → 创建 CoolCommand → 执行 → 温度下降
玩家点击 撤销按钮 → 弹出栈顶命令 → 调用 Undo → 恢复上一次状态
7. 注意事项总结
撤销操作需记录状态:在 Execute 前保存当前状态
命令对象独立:命令类只调用接收者方法,不处理 UI
调用者解耦接收者:UI 或系统只与 CommandInvoker 交互
8. 扩展思考
可以结合 对象池模式,回收命令对象,减少 GC
可以记录操作序列 → 实现实验回放
可以结合 观察者模式 → UI 或日志自动更新
9. 总结
通过这个虚拟仿真案例,你学会了:
使用 命令模式 封装实验操作
支持撤销操作,操作管理清晰
调用者和接收者解耦,易于扩展新操作
👉 命令模式在虚拟实验系统中,非常适合操作管理、撤销与回放功能,提升实验交互体验。