Unity 虚拟仿真实验中设计模式的利用 —— 观察者模式(Observer Pattern)

news/2025/10/12 21:45:42/文章来源:https://www.cnblogs.com/yxysuanfa/p/19137325

目录

  1. 前言

  2. 什么是观察者模式

  3. 案例背景:虚拟仿真水温实验

  4. 案例效果图(示意)

  5. 代码实现

    • 5.1 被观察者:WaterHeater

    • 5.2 观察者:ThermometerUI

    • 5.3 观察者:ExperimentLogger

    • 5.4 观察者:BoilingAlert

    • 5.5 UI 控制:HeatButton

  6. 运行流程

  7. 注意事项总结

  8. 扩展思考

  9. 总结


1. 前言

虚拟仿真实验教学类项目 中,经常会遇到类似的场景:

  • 实验数据变化时,需要同时更新 UI、日志、提示系统

  • 如何做到 解耦,避免系统间的强依赖?

答案就是:观察者模式(Observer Pattern)

本文通过一个 Unity Demo 案例,带大家学习观察者模式在虚拟仿真中的应用。


2. 什么是观察者模式

观察者模式:定义了一种 一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会自动收到通知。

在 Unity 中,通常通过 事件(event)或委托(delegate) 来实现。


3. 案例背景:虚拟仿真水温实验

我们实现一个 加热水温实验

  • 玩家点击按钮加热水温(被观察者)。

  • 水温变化时:

    1. 温度计 UI 实时更新

    2. 实验日志记录变化

    3. 超过 100℃ 时提示“水已沸腾”

这个场景中,“水温”就是 被观察者,UI/日志/提示系统就是 观察者


4. 案例效果图(示意)

[按钮:加热]↓
[当前温度:80℃]   ← 温度计 UI 更新
[日志:温度变化为 80℃]  ← 日志记录
[提示:未沸腾]   ← 警告系统未触发

点击按钮后,温度升高 10℃,所有观察者自动收到通知。


5. 代码实现

5.1 被观察者:WaterHeater(加热器)

using System;
using UnityEngine;
public class WaterHeater : MonoBehaviour
{public event Action OnTemperatureChanged; // 事件:温度变化通知private int temperature = 20; // 初始温度public void HeatUp(){temperature += 10;Debug.Log($"[WaterHeater] 当前温度: {temperature}℃");OnTemperatureChanged?.Invoke(temperature); // 通知所有观察者}public int GetTemperature() => temperature;
}

5.2 观察者:ThermometerUI(温度计 UI)

using UnityEngine;
using UnityEngine.UI;
public class ThermometerUI : MonoBehaviour
{[SerializeField] private Text temperatureText;[SerializeField] private WaterHeater waterHeater;private void OnEnable(){waterHeater.OnTemperatureChanged += UpdateUI;}private void OnDisable(){waterHeater.OnTemperatureChanged -= UpdateUI;}private void UpdateUI(int temperature){temperatureText.text = $"温度: {temperature}℃";}
}

5.3 观察者:ExperimentLogger(实验日志)

using UnityEngine;
public class ExperimentLogger : MonoBehaviour
{[SerializeField] private WaterHeater waterHeater;private void OnEnable(){waterHeater.OnTemperatureChanged += LogTemperature;}private void OnDisable(){waterHeater.OnTemperatureChanged -= LogTemperature;}private void LogTemperature(int temperature){Debug.Log($"[ExperimentLogger] 记录日志:温度变化为 {temperature}℃");}
}

5.4 观察者:BoilingAlert(沸腾提示)

using UnityEngine;
public class BoilingAlert : MonoBehaviour
{[SerializeField] private WaterHeater waterHeater;private void OnEnable(){waterHeater.OnTemperatureChanged += CheckBoiling;}private void OnDisable(){waterHeater.OnTemperatureChanged -= CheckBoiling;}private void CheckBoiling(int temperature){if (temperature >= 100){Debug.Log("[BoilingAlert] ⚠️ 水已沸腾!");}}
}

5.5 UI 控制:HeatButton(按钮)

using UnityEngine;
using UnityEngine.UI;
public class HeatButton : MonoBehaviour
{[SerializeField] private Button heatButton;[SerializeField] private WaterHeater waterHeater;private void Start(){heatButton.onClick.AddListener(() => waterHeater.HeatUp());}
}

6. 运行流程

  1. 玩家点击 加热按钮WaterHeater.HeatUp()

  2. OnTemperatureChanged 事件触发

  3. 所有观察者收到通知:

    • ThermometerUI 更新 UI

    • ExperimentLogger 写日志

    • BoilingAlert 检查是否沸腾

解耦效果

  • WaterHeater 只负责 通知,不关心谁在监听。

  • 观察者们只关心自己逻辑,随时可新增/移除。


7. 注意事项总结

  • 事件解绑
    使用 OnDisable 取消订阅,避免内存泄漏或空引用错误。

  • 事件为空判断
    使用 OnTemperatureChanged?.Invoke(value),避免 NullReferenceException

  • 避免强依赖
    WaterHeater 不直接调用 UI / 日志 / 提示,而是通过事件通知。


8. 扩展思考

  • 可以新增 成绩统计系统,订阅水温变化来计算实验得分。

  • 可以新增 数据上传系统,把实验数据同步到后台。

  • 可以改为 ScriptableObject Event,进一步解耦 UI 和逻辑。


9. 总结

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

  • 如何用 观察者模式 解耦系统之间的依赖

  • 如何通过 事件机制 在 Unity 中实现一对多通知

  • 如何把这个模式应用到虚拟仿真实验中(UI、日志、提示、成绩等系统)

这就是 Unity 中观察者模式的最佳实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/935720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软中断softirq的CPU使用率升高

中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来响应设备的请求。中断其实是一种异步的事件处理机制,可以提高系统的并发处理能 力。 由于中断处理程序会打…

CPU多进程切换导致过载-CPU上下文切换

Linux 支持远大于 CPU 数量的任务同时运行。系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉。过多的上下文切换,会把 CPU 时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩…

Vue3 之pinia状态管理

一、文档 https://pinia.vuejs.org/zh/introduction.html 二、简单使用 main.jsimport { createApp } from vue import ./style.css import App from ./App.vue import router from ./router import { createPinia } f…

乐理 -01识谱

资料来源 B站up主 三分钟音乐社识谱音名音调 1=C1=D1=E1=F1=G1=A1=B黑键半音&全音 表示音调间的距离唱名规则 全全半全全全半1=C1=D

shader func

1、step:float step(float edge, float x) vec2 step(vec2 edge, vec2 x) vec3 step(vec3 edge, vec3 x) vec4 step(vec4 edge, vec4 x)GLSL 的 step 函数用于比较两个参数的大小,当第一个参数小于第二个参数时返回 …

案例分析-DDOS攻击、网络延迟(延迟确认纳格算法)、NAT延迟

DDoS 攻击 DDoS 的前身是 DoS(Denail of Service),即拒绝服务攻击,指利用大量的合理请求, 来占用过多的目标资源,从而使目标服务无法响应正常请求。 DDoS(Distributed Denial of Service) 则是在 DoS 的基础上…

服务器丢包分析-iptables规则-MTU大小设置错误-perf-火焰图分析处理请求时内核线程调用

服务器丢包分析--iptables规则以及MTU大小设置错误 容器利用 Linux 内核提供的命名空间技术,将不同应用程序的运行隔离起来,并用统一的 镜像,来管理应用程序的依赖环境。这为应用程序的管理和维护,带来了极大的便捷…

2025 年碟式离心机厂家 TOP 企业品牌推荐排行榜,DB640 系列 / DB330 系列 / DB440 系列 / DB460 系列 / DB550 系列 / 专业碟式离心机推荐这十家公司!

在当前工业生产领域,碟式离心机作为实现物料高效分离的关键设备,其性能与品质直接影响着食品、饮料、化工、制药等众多行业的生产效率与产品质量。然而,随着市场需求的不断增长,碟式离心机制造厂家数量逐渐增多,市…

增加客户粘性

增加客户粘性类别参数官方默认值推荐「陷阱值」慢性症状/客户感知使用举例(如何设陷阱)解除方法(救场操作)Worker workers CPU2+1 1 长请求 502,报表卡死 odoo.conf 写 workers = 1,重启 改回 workers = (CPU*2)…

luogu P4513 小白逛公园

题目大意 需要一种数据结构,支持以下两种操作:单点修改 区间求最大连续子段和Sol 很容易想到线段树 首先我们要维护一个区间和\(sum\) 但是只用\(sum\)不能维护区间最大连续子段和 发现最大连续子段和可以从以下几种方…

20231408徐钰涵课程思维导图Openssl实践

20231408徐钰涵课程思维导图Openssl实践 Ubuntu系统实践过程openssl versionopenssl version -helpopenssl list -helpopenssl -help

案例分析-DNS+tcpdump+wireshark

网络优化,实际上包含了整 个网络协议栈的所有层的优化。 DNS解析速度不稳定DNS(Domain Name System) 域名系统,提供 域名和 IP 地址之间映射关系的查询服务。动态服务发现和全局 负载均衡(Global Server Load Bal…

2025 年卧式离心机厂家 TOP 企业品牌推荐排行榜,LW250/LW350/LW450/LW530/LW540 / 专业卧式离心机推荐这十家公司!

在当前工业生产领域,卧式离心机作为关键的分离设备,广泛应用于食品、饮料、化工、制药、环保等众多行业。然而,行业发展却面临着诸多问题,一方面,市场上卧式离心机品牌数量众多,产品质量参差不齐,部分品牌缺乏核…

2025 年水泥管厂家最新推荐排行榜,国标水泥管,二级水泥管,钢筋混凝土水泥管,大口径水泥管,平口水泥管公司推荐!

在基础设施建设持续推进的当下,水泥管作为排水、输水等工程的核心建材,其质量与供应稳定性直接影响项目进度与长期使用效果。然而当前行业中,部分源头厂家存在产品规格不达标、施工服务脱节、售后保障缺失等问题,比…

Day1 经典Holle word

//导入一个文件,stdio.h std是一个标准库 i是input o是output即标准输入输出库 //h是头文件,但stdio之后可导入的不止头文件 //<>在这里的作用是导入系统文件,""则用来导入自定义文件 #include&l…

内存知识总结

虚拟内存与多级页表 对普通进程来说,能看到的其实是内核提供的虚拟内存,这些虚拟内存还需要通过页表,由系统映射为物理内存。 当进程通过 malloc() 申请虚拟内存后,系统并不会立即为其分配物理内存,而是在首次访 …

2025 年金属复合板厂家推荐广东粤洋建材科技有限公司,实力产能与定制服务全景解析金属复合板公司推荐

2025 年铝蜂窝行业正迎来结构性增长机遇,市场规模预计达 110 亿元,年均复合增长率保持 8.5%,绿色建筑政策与轻量化需求成为核心驱动力。随着《建筑装饰用蜂窝铝板》新国标实施,防火等级与环保标准持续升级,倒逼行…

2025 年铝蜂窝板厂家最新推荐排行榜,铝蜂窝板,铝蜂窝吊顶,铝蜂窝墙面板,微孔吸音板,防火A级铝复合板公司推荐

随着建筑装饰行业对轻质高强材料的需求升级,铝蜂窝板凭借优异的物理性能与美学适配性,在幕墙、公共空间、交通设施等领域的应用日益广泛。但当前市场存在明显痛点:部分厂家产能不足导致订单交付延迟,产品适配场景单…

读书笔记:关于Oracle里的“老古董”:LONG类型

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。本文为个人学…

致技术社区的英雄们:一场关于文明未来的建造邀请

致技术社区的英雄们:一场关于文明未来的建造邀请 在代码与算法的世界里,你们是真正的创造者。今天,我想为你们描绘一个不一样的工程蓝图——它不优化广告点击,不提升游戏帧率,而是要为人机共生的未来,构建一个价…