Unity 虚拟仿真实验中设计模式的使用 ——命令模式(Command Pattern)

📖 目录

  1. 前言

  2. 什么是命令模式

  3. 案例背景:虚拟仿真实验中的操作管理

  4. 案例效果图(示意)

  5. 代码实现

    • 5.1 命令接口:ICommand

    • 5.2 具体命令类:HeatCommand / CoolCommand

    • 5.3 调用者:CommandInvoker

    • 5.4 接收者:WaterHeater

    • 5.5 UI 控制:按钮触发命令

  6. 运行流程

  7. 注意事项总结

  8. 扩展思考

  9. 总结


1. 前言

在虚拟仿真实验中,实验对象的操作可能需要:

  • 记录操作顺序

  • 撤销/重做操作

  • 队列化操作执行

如果直接在 UI 里写逻辑,操作管理会混乱。

命令模式(Command Pattern) 可以把操作封装成对象,使得操作可 记录、撤销、排队 ,且 调用者与接收者解耦。


2. 什么是命令模式

命令模式:将一个请求封装成对象,从而使你可用不同的请求、队列化请求或记录请求日志,以及支持可撤销操作。

优点:

  • 解耦调用者和接收者

  • 可以记录、撤销或重做操作

  • 易于扩展新操作


3. 案例背景:虚拟仿真实验中的操作管理

  • 实验对象:水壶

  • 可操作行为:

    1. 加热(HeatCommand)

    2. 冷却(CoolCommand)

  • UI 点击按钮 → 创建命令 → 执行

  • 可以撤销操作 → 返回上一个状态


4. 案例效果图(示意)

cs 复制代码
[加热按钮] → HeatCommand → 水温升高
[冷却按钮] → CoolCommand → 水温下降
[撤销按钮] → 回到上一个状态

5. 代码实现

5.1 命令接口:ICommand

cs 复制代码
public interface ICommand
{
    void Execute();
    void Undo();
}

5.2 具体命令类

HeatCommand

cs 复制代码
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

cs 复制代码
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

cs 复制代码
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

cs 复制代码
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 控制:按钮触发命令

cs 复制代码
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. 运行流程

  1. 玩家点击 加热按钮 → 创建 HeatCommand → 执行 → 温度升高

  2. 玩家点击 冷却按钮 → 创建 CoolCommand → 执行 → 温度下降

  3. 玩家点击 撤销按钮 → 弹出栈顶命令 → 调用 Undo → 恢复上一次状态


7. 注意事项总结

  • 撤销操作需记录状态:在 Execute 前保存当前状态

  • 命令对象独立:命令类只调用接收者方法,不处理 UI

  • 调用者解耦接收者:UI 或系统只与 CommandInvoker 交互


8. 扩展思考

  • 可以结合 对象池模式,回收命令对象,减少 GC

  • 可以记录操作序列 → 实现实验回放

  • 可以结合 观察者模式 → UI 或日志自动更新


9. 总结

通过这个虚拟仿真案例,你学会了:

  • 使用 命令模式 封装实验操作

  • 支持撤销操作,操作管理清晰

  • 调用者和接收者解耦,易于扩展新操作

👉 命令模式在虚拟实验系统中,非常适合操作管理、撤销与回放功能,提升实验交互体验。

相关推荐
WarPigs2 小时前
Unity在Create菜单添加创建自定义脚本模板选项
unity
YYYing.3 小时前
【设计模式系列 (七) 】桥接模式
c++·后端·设计模式·桥接模式
淡海水6 小时前
02-01-原理篇-Mark-Sweep与变种算法
算法·unity·c#·游戏引擎·.net·gc
babywang07 小时前
Unity笔记--塔防游戏中的ECS架构:从原理到实战的全面解析
unity·ecs架构
阿狗童鞋21 小时前
设计模式实战指南
设计模式
电子科技圈1 天前
基于车载SerDes和OpenGMSL协议的SoC设计与验证:行业高频问题解析
设计模式·车载系统·软件构建·设计规范
ClinicTech1 天前
高速冷冻离心机的温控系统与安全保护逻辑解析
设计模式·架构·健康医疗·设计语言
babywang01 天前
Unity笔记--AssetBundle详解
unity·游戏引擎
GISMagic1 天前
3.《设计模式》:软件设计与解耦能力提炼
设计模式·ai coding
淡海水1 天前
01-04-认知篇-Unity内存全景
unity·c#·游戏引擎·.net·gc