📖 目录
-
前言
-
什么是状态模式
-
案例背景:虚拟仿真实验中的仪器状态管理
-
案例效果图(示意)
-
代码实现
-
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. 案例效果图(示意)
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. 运行流程
-
初始状态:Idle
-
点击 加热按钮 → 状态切换到 Heating
-
温度持续上升,HeatingState.Execute 检测温度
-
温度 >= 100 → 状态切换到 Boiling
-
每个状态 Enter/Execute/Exit 行为独立
7. 注意事项总结
-
每个状态类应只关注自身行为
-
状态切换统一通过
ChangeState()
管理 -
避免在状态类中直接操作其他状态
-
Update 内只调用当前状态 Execute
8. 扩展思考
-
可以结合 观察者模式,状态变化通知 UI/日志
-
可以结合 策略模式,不同实验对象有不同加热策略
-
可以增加 Idle→CoolingState,模拟自然冷却
9. 总结
通过这个虚拟仿真案例,你学会了:
-
使用 状态模式 管理实验对象行为
-
每个状态独立、可扩展
-
避免大量 if-else,使虚拟实验逻辑清晰
👉 状态模式 + 观察者模式 可以让虚拟实验系统既灵活又可维护。