Unity 虚拟仿真实验中设计模式的使用 ——状态模式(State Pattern)

📖 目录

  1. 前言

  2. 什么是状态模式

  3. 案例背景:虚拟仿真实验中的仪器状态管理

  4. 案例效果图(示意)

  5. 代码实现

    • 5.1 状态接口:IState

    • 5.2 具体状态类:IdleState / HeatingState / BoilingState

    • 5.3 状态管理器:WaterStateMachine

    • 5.4 UI 控制:状态切换按钮

  6. 运行流程

  7. 注意事项总结

  8. 扩展思考

  9. 总结


1. 前言

在虚拟仿真实验中,实验对象通常会有 多种状态,比如:

  • 水壶:空闲、加热、沸腾

  • 烧杯:空、注入液体、混合

  • 仪器:待机、运行、故障

如果用 大量 if-else 判断状态,代码会混乱且难以维护。

状态模式(State Pattern) 可以把对象的每个状态封装成类,实现 状态切换灵活、行为清晰


2. 什么是状态模式

状态模式 :允许对象在内部状态变化时改变行为,使得对象看起来好像 改变了类

优点

  • 每个状态独立,易于维护

  • 避免大量 if-else

  • 状态切换灵活,可扩展


3. 案例背景:虚拟仿真实验中的仪器状态管理

  • 我们用 加热水实验 作为例子

  • 水壶状态:

    1. Idle:水温 < 20℃,未加热

    2. Heating:温度升高 20~100℃

    3. Boiling:温度 >= 100℃

  • 不同状态下,仪器行为不同:

    • Idle:显示等待

    • Heating:UI 显示加热动画

    • Boiling:提示沸腾、触发事件


4. 案例效果图(示意)

css 复制代码
[加热按钮] → 水壶状态变化
Idle → Heating → Boiling
每个状态显示不同UI/提示

5. 代码实现

5.1 状态接口:IState

cs 复制代码
public interface IState
{
    void Enter();   // 进入状态
    void Execute(); // 状态行为
    void Exit();    // 退出状态
}

5.2 具体状态类

IdleState

cs 复制代码
using UnityEngine;

public class IdleState : IState
{
    private WaterStateMachine water;

    public IdleState(WaterStateMachine water) { this.water = water; }

    public void Enter() { Debug.Log("进入空闲状态"); }
    public void Execute() { /* 等待加热 */ }
    public void Exit() { Debug.Log("退出空闲状态"); }
}

HeatingState

cs 复制代码
using UnityEngine;

public class HeatingState : IState
{
    private WaterStateMachine water;

    public HeatingState(WaterStateMachine water) { this.water = water; }

    public void Enter() { Debug.Log("开始加热"); }
    public void Execute()
    {
        water.Temperature += 10 * Time.deltaTime;
        Debug.Log($"加热中,温度:{water.Temperature:F1}℃");
        if (water.Temperature >= 100)
        {
            water.ChangeState(new BoilingState(water));
        }
    }
    public void Exit() { Debug.Log("停止加热"); }
}

BoilingState

cs 复制代码
using UnityEngine;

public class BoilingState : IState
{
    private WaterStateMachine water;

    public BoilingState(WaterStateMachine water) { this.water = water; }

    public void Enter() { Debug.Log("水已沸腾!"); }
    public void Execute() { /* 持续沸腾逻辑 */ }
    public void Exit() { Debug.Log("退出沸腾状态"); }
}

5.3 状态管理器:WaterStateMachine

cs 复制代码
using UnityEngine;

public class WaterStateMachine : MonoBehaviour
{
    private IState currentState;

    public float Temperature { get; set; } = 20f;

    private void Start()
    {
        ChangeState(new IdleState(this));
    }

    private void Update()
    {
        currentState?.Execute();
    }

    public void ChangeState(IState newState)
    {
        currentState?.Exit();
        currentState = newState;
        currentState?.Enter();
    }

    // 按钮点击调用
    public void StartHeating()
    {
        ChangeState(new HeatingState(this));
    }
}

5.4 UI 控制:状态切换按钮

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class WaterUI : MonoBehaviour
{
    [SerializeField] private Button heatButton;
    [SerializeField] private WaterStateMachine waterMachine;

    private void Start()
    {
        heatButton.onClick.AddListener(() => waterMachine.StartHeating());
    }
}

6. 运行流程

  1. 初始状态:Idle

  2. 点击 加热按钮 → 状态切换到 Heating

  3. 温度持续上升,HeatingState.Execute 检测温度

  4. 温度 >= 100 → 状态切换到 Boiling

  5. 每个状态 Enter/Execute/Exit 行为独立


7. 注意事项总结

  • 每个状态类应只关注自身行为

  • 状态切换统一通过 ChangeState() 管理

  • 避免在状态类中直接操作其他状态

  • Update 内只调用当前状态 Execute


8. 扩展思考

  • 可以结合 观察者模式,状态变化通知 UI/日志

  • 可以结合 策略模式,不同实验对象有不同加热策略

  • 可以增加 Idle→CoolingState,模拟自然冷却


9. 总结

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

  • 使用 状态模式 管理实验对象行为

  • 每个状态独立、可扩展

  • 避免大量 if-else,使虚拟实验逻辑清晰

👉 状态模式 + 观察者模式 可以让虚拟实验系统既灵活又可维护。

相关推荐
饮茶三千25 分钟前
电子保函模板编辑器实战二:HTML→FTL 编译转换的设计与实现
前端·vue.js·设计模式
Kel30 分钟前
Node.js 本质:从全脉络视角理解运行时原理
javascript·设计模式·node.js
码哥字节2 小时前
11 万 Star 的 Spec Kit,90% 的工程师只用它解决了 10% 的问题
设计模式·vibe coding·github spec kit
我登哥MVP2 小时前
走进 Gang of Four 设计模式:访问者模式
java·设计模式·访问者模式·原型模式
ttod_qzstudio4 小时前
【软考设计模式】状态模式:状态驱动行为自动转换与代码填空精讲
设计模式·状态模式
饮茶三千4 小时前
基于 WangEditor 的富文本编辑器定制实践
前端·vue.js·设计模式
折哥的程序人生 · 物流技术专研5 小时前
Java 23 种设计模式:从踩坑到精通 | 番外:状态 vs 策略 —— if-else 消除的两条路,你走对了吗?
java·spring·状态模式·策略模式·java面试·java设计模式·从踩坑到精通
xiaotie10055 小时前
给deerflow2.0增加模型Token 使用数量显示的功能
状态模式
ttod_qzstudio6 小时前
【软考设计模式】中介者模式:网状交互的解耦与集中调度精讲
设计模式·中介者模式
玖玥拾1 天前
C# 语言进阶(十四)Unity UI界面开发 + 网络消息联动
服务器·开发语言·网络·ui·unity·c#·游戏引擎