Unity 虚拟仿真实验中设计模式的使用 ——状态模式(State Pattern)
📖 目录
前言
什么是状态模式
案例背景:虚拟仿真实验中的仪器状态管理
案例效果图(示意)
代码实现
5.1 状态接口:IState
5.2 具体状态类:IdleState / HeatingState / BoilingState
5.3 状态管理器:WaterStateMachine
5.4 UI 控制:状态切换按钮
运行流程
注意事项总结
扩展思考
总结
1. 前言
在虚拟仿真实验中,实验对象通常会有 多种状态,比如:
水壶:空闲、加热、沸腾
烧杯:空、注入液体、混合
仪器:待机、运行、故障
如果用 大量 if-else 判断状态,代码会混乱且难以维护。
状态模式(State Pattern) 可以把对象的每个状态封装成类,实现 状态切换灵活、行为清晰。
2. 什么是状态模式
状态模式:允许对象在内部状态变化时改变行为,使得对象看起来好像 改变了类。
优点:
每个状态独立,易于维护
避免大量 if-else
状态切换灵活,可扩展
3. 案例背景:虚拟仿真实验中的仪器状态管理
我们用 加热水实验 作为例子
水壶状态:
Idle:水温 < 20℃,未加热
Heating:温度升高 20~100℃
Boiling:温度 >= 100℃
不同状态下,仪器行为不同:
Idle:显示等待
Heating:UI 显示加热动画
Boiling:提示沸腾、触发事件
4. 案例效果图(示意)
[加热按钮] → 水壶状态变化
Idle → Heating → Boiling
每个状态显示不同UI/提示
5. 代码实现
5.1 状态接口:IState
public interface IState
{void Enter(); // 进入状态void Execute(); // 状态行为void Exit(); // 退出状态
}
5.2 具体状态类
IdleState
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
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
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
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 控制:状态切换按钮
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. 运行流程
初始状态:Idle
点击 加热按钮 → 状态切换到 Heating
温度持续上升,HeatingState.Execute 检测温度
温度 >= 100 → 状态切换到 Boiling
每个状态 Enter/Execute/Exit 行为独立
7. 注意事项总结
每个状态类应只关注自身行为
状态切换统一通过
ChangeState()
管理避免在状态类中直接操作其他状态
Update 内只调用当前状态 Execute
8. 扩展思考
可以结合 观察者模式,状态变化通知 UI/日志
可以结合 策略模式,不同实验对象有不同加热策略
可以增加 Idle→CoolingState,模拟自然冷却
9. 总结
通过这个虚拟仿真案例,你学会了:
使用 状态模式 管理实验对象行为
每个状态独立、可扩展
避免大量 if-else,使虚拟实验逻辑清晰
👉 状态模式 + 观察者模式 可以让虚拟实验系统既灵活又可维护。