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,使虚拟实验逻辑清晰

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

相关推荐
小贺儿开发4 小时前
Unity 结合百度AI开放平台 手写文字识别
人工智能·科技·学习·unity·云服务·文字识别·手写文字
Zane19947 小时前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..8 小时前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
林川~0117 小时前
Unity 万能物理检测工具:射线检测 / 范围检测 / 层级过滤 / 编辑器可视化(可直接拿去用)
游戏·unity·c#·射线检测·通用工具
xiaofeiyang15018 小时前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
yi碗汤园1 天前
MQTT消息队列遥测传输协议
网络·网络协议·unity
林川~011 天前
Unity 常用 API 与核心类全解:从生命周期到协程,附性能避坑清单(Unity 6 适配)
unity·游戏引擎·常用api
sensen_kiss1 天前
CPT306 Coursework 1 个人游戏作业——坦克大战
unity·游戏程序·游戏策划
蒸鱼Yuzheng1 天前
Unity 与 Unreal 测试工具怎么回答:Profiler、日志、自动化与证据链
测试工具·unity·性能分析·游戏测试·unrealengine
Shadow(⊙o⊙)1 天前
OTOL设计模式 One Thread One Loop
服务器·网络·设计模式