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,使虚拟实验逻辑清晰
状态模式 + 观察者模式 可以让虚拟实验系统既灵活又可维护。
浙公网安备 33010602011771号