Unity 观察者模式(实例详解)

文章目录

    • 简介
      • 示例1 - 简单的文本更新通知
      • 示例2 - 多观察者监听游戏分数变化
      • 示例3 - 事件系统实现观察者模式
      • 示例4 - 泛型观察者和可序列化的事件系统
      • 示例5 - 使用C#委托简化版

简介

在Unity中实现观察者模式,我们可以创建一个Subject(目标/主题)类,它负责维护订阅者列表,并且当其状态改变时通知所有观察者。下面通过5个代码示例来详细展示如何在Unity C#脚本中应用观察者模式:

示例1 - 简单的文本更新通知

using System.Collections;
using System.Collections.Generic;// 观察者接口
public interface IObserver
{void OnUpdate(string message);
}// 被观察者接口
public interface IObservable
{void Register(IObserver observer);void Remove(IObserver observer);void NotifyObservers(string message);
}// 具体的被观察者类
public class TextDisplay : MonoBehaviour, IObservable
{private List<IObserver> observers = new List<IObserver>();public void Register(IObserver observer){observers.Add(observer);}public void Remove(IObserver observer){observers.Remove(observer);}public void NotifyObservers(string message){foreach (var observer in observers){observer.OnUpdate(message);}}// 模拟状态改变public void UpdateText(string newText){Debug.Log("Text has been updated to: " + newText);NotifyObservers(newText);}
}// 具体的观察者类
public class ConsoleLogger : MonoBehaviour, IObserver
{public void OnUpdate(string message){Debug.Log("Console Logger received update: " + message);}
}// 使用示例
public class GameManager : MonoBehaviour
{public TextDisplay display;public ConsoleLogger logger;void Start(){display.Register(logger);display.UpdateText("Hello, World!");}
}

示例2 - 多观察者监听游戏分数变化

public interface IScoreObserver : IObserver
{void OnScoreChanged(int newScore);
}public class ScoreManager : MonoBehaviour, IObservable
{private List<IScoreObserver> scoreObservers = new List<IScoreObserver>();public void Register(IScoreObserver observer){scoreObservers.Add(observer);}public void Remove(IScoreObserver observer){scoreObservers.Remove(observer);}public void NotifyScoreObservers(int newScore){foreach (var observer in scoreObservers){observer.OnScoreChanged(newScore);}}public void IncreaseScore(int points){int currentScore = GetTotalScore(); // 假设这是一个获取当前分数的方法int newScore = currentScore + points;SetTotalScore(newScore); // 假设这是一个设置总分数的方法NotifyScoreObservers(newScore);}
}public class ScoreUI : MonoBehaviour, IScoreObserver
{public void OnScoreChanged(int newScore){GetComponent<Text>().text = "Score: " + newScore;}
}public class HighScoreTracker : MonoBehaviour, IScoreObserver
{public void OnScoreChanged(int newScore){if (newScore > PlayerPrefs.GetInt("HighScore")){PlayerPrefs.SetInt("HighScore", newScore);}}
}// 使用示例
public class GameInitializer : MonoBehaviour
{public ScoreManager scoreManager;public ScoreUI scoreUI;public HighScoreTracker highScoreTracker;void Start(){scoreManager.Register(scoreUI);scoreManager.Register(highScoreTracker);// 游戏过程中调用scoreManager.IncreaseScore()增加分数}
}

示例3 - 事件系统实现观察者模式

using UnityEngine.Events;public class SubjectWithEvent : MonoBehaviour
{public UnityEvent<string> OnTextUpdated;public void UpdateText(string newText){Debug.Log("Text has been updated to: " + newText);OnTextUpdated.Invoke(newText);}
}public class ObserverUsingEvent : MonoBehaviour
{public SubjectWithEvent subject;void Start(){subject.OnTextUpdated.AddListener(OnTextUpdatedHandler);}void OnDestroy(){subject.OnTextUpdated.RemoveListener(OnTextUpdatedHandler);}void OnTextUpdatedHandler(string message){Debug.Log("Received text update: " + message);}
}

示例4 - 泛型观察者和可序列化的事件系统

[System.Serializable]
public class GenericEvent<T> : UnityEvent<T>
{
}public class ObservableGeneric<T> : MonoBehaviour
{public GenericEvent<T> OnStateChanged;public T State { get; private set; }public void ChangeState(T newState){State = newState;OnStateChanged?.Invoke(newState);}
}public class ObserverForGeneric<T> : MonoBehaviour
{public ObservableGeneric<T> observable;public void Awake(){observable.OnStateChanged.AddListener(StateChangedHandler);}public void OnDestroy(){observable.OnStateChanged.RemoveListener(StateChangedHandler);}void StateChangedHandler(T newState){Debug.Log($"New state received: {newState}");}
}// 使用示例
public class ExampleUsage : MonoBehaviour
{public ObservableGeneric<int> healthObservable;public ObserverForGeneric<int> healthObserver;void Start(){healthObserver.observable = healthObservable;}
}

示例5 - 使用C#委托简化版

public class SimpleObservable
{public delegate void MessageEventHandler(string message);public event MessageEventHandler OnMessageEvent;public void SendMessage(string message){OnMessageEvent?.Invoke(message);}
}public class SimpleObserver : MonoBehaviour
{public SimpleObservable observable;void Start(){observable.OnMessageEvent += HandleMessageEvent;}void OnDestroy(){observable.OnMessageEvent -= HandleMessageEvent;}void HandleMessageEvent(string message){Debug.Log("Received message: " + message);}
}// 使用示例
public class SimpleExample : MonoBehaviour
{public SimpleObservable messageSource;public SimpleObserver messageRecipient;void Start(){messageRecipient.observable = messageSource;messageSource.SendMessage("Hello from the Observable");}
}

以上每个示例都展示了观察者模式的基本原理:当被观察者的状态发生改变时,它会通知所有已注册的观察者进行相应的响应或更新操作。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

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

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

相关文章

前端面试题-js部分-数组去重-数组扁平化-伪数组转数组-面向对象的继承方式(ES5)

前端面试题-js部分-数组去重-数组扁平化-伪数组转数组-面向对象的继承方式ES5 数组去重数组扁平化伪数组转换为数组面向对象的继承方式&#xff08;ES5&#xff09; 数组去重 1.利用es6 set 去重 Set 类型不允许有值重复 let arr1 [1, 2, 4, 3, 5, 7, 1, 8, 2, 4, 9]console.…

WebRTC系列-自定义媒体数据加密

文章目录 1. 对外加密接口2. 对外加密实现前面的文章都有提过WebRTC使用的加密方式是SRTP这个库提供的,这个三方库这里就不做介绍,主要是对rtp包进行加密;自然的其调用也是WebRTC的rtp相关模块;同时在WebRTC里也提供一个自定义加密的接口,本文将围绕这个接口做介绍及分析;…

【郑益慧】模拟电子技术:7.Mos管的工作原理

Mos管的工作原理 Mos管的出现&#xff0c;几乎不怎么耗电。因此在集成电路中起了非常大的作用 在某些方面确实比晶体三极管强。 基本原理&#xff1a;依靠电场效应来控制。 电场效应几乎是没有电流的&#xff0c;没有电流几乎是没有功率的。 从控制上来说&#xff0c;消耗…

华为——NGFW Module安装在集群交换机上,二层双机负载分担部署,交换机重定向引流

NGFW Module安装在集群交换机上&#xff0c;二层双机负载分担部署&#xff0c;交换机重定向引流 业务需求 如图1所示&#xff0c;两台交换机集群组网&#xff0c;两块NGFW Module分别安装在两台交换机的1号槽位组成双机负载分担组网。NGFW Module工作在二层&#xff0c;也就是…

微信小程序canvas画布实现文字自由缩放、移动功能

目录 实现效果 一、获取画布信息并绘制背景 二、绘制文字 三、绘制文字编辑按钮

铺砖4(c++题解)

题目描述 你有一个长为N宽为2的墙壁&#xff0c;给你两种砖头&#xff1a;一个长2宽1&#xff0c;另一个是L型覆盖3个单元的砖头。如下图&#xff1a; 砖头可以旋转&#xff0c;两种砖头可以无限制提供。你的任务是计算用这两种来覆盖N*2的墙壁的覆盖方法。例如一个2*3的墙可…

Stable Diffusion结构解析-以图像生成图像!

手把手教你入门绘图超强的AI绘画&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。给大家带来了全新保姆级教程资料包 &#xff08;文末可获取&#xff09; AIGC专栏3——Stable Diffusion结构解析-以图像生成图像&#xff08;图生图&#xff0c…

【活动回顾】CSDN 1024 程序员节城市站系列活动·成都站 - 圆满结束!

文章目录 前言一、活动介绍二、精彩分享内容及活动议程2.1、1024 活动限量周边大放送2.2、《COC 成都社区情况和活动介绍》2.3、CSDN 创始人蒋涛寄语2.4、《AI 重构世界》2.5、《新技术助力企业降本增效》2.6、现场互动情况2.7、《探索开源世界&#xff0c;开拓创新思路》2.8、…

用C#实现最小二乘法(用OxyPlot绘图)

最小二乘法介绍✨ 最小二乘法&#xff08;Least Squares Method&#xff09;是一种常见的数学优化技术&#xff0c;广泛应用于数据拟合、回归分析和参数估计等领域。其目标是通过最小化残差平方和来找到一组参数&#xff0c;使得模型预测值与观测值之间的差异最小化。 最小二…

RSTP保护机制

BPDU保护 在交换设备上通常将直接与用户终端或文件服务器等非交换机设备相连的端口配置为边缘端口。 正常情况下&#xff0c;边缘端口不会收到RST BPDU。如果有人伪造RST BPDU恶意攻击交换设备&#xff0c;当边缘端口接收到RST BPDU时&#xff0c;交换设备会自动将边缘端口设置…

TensorFlow2实战-系列教程8:TFRecords数据源制作2

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 5、图像数据处理实例 5.1 读数据 import os import glob from datetime import date…

【Qt】QInputDialog setGeometry: Unable to set geometry 问题

QInputDialog setGeometry: Unable to set geometry 问题 文章目录 I - 问题背景II - 解决办法III - 参考链接 I - 问题背景 创建了一个 QMainWindow 并在上边创建了布局&#xff0c;尝试调用 QInputDialog 的 getInt 静态方法&#xff0c;结果运行时出现了以下警告 QWindows…

电商API接口的应用|电商跨境电商商品采集高效解决方案

电商API接口的应用|电商跨境电商商品采集高效解决方案 面对数十万亿元的跨境电商市场&#xff0c;以阿里巴巴国际站为代表的跨境电商数字平台&#xff0c;在政策、需求以及供应链的驱动下&#xff0c;为中小企业提供了全产业链、全供应链一体化综合服务&#xff0c;让越来越多…

机器学习复习(1)——任务整理流程

目录 固定的随机数种子 定义predict功能 拆分数据集 定义trainer 超参数设置 数据集载入 固定的随机数种子 在大量的机器学习与深度学习实验中&#xff0c;如果不进行特殊设置&#xff0c;我们的结果将不可复现&#xff0c;固定的随机数种子将会解决这个问题 def same…

字符串相关函数和文件操作

文章目录 1. C/C 字符串概述1.1 字符串常量1.2 字符数组 2. 字符串函数2.1 拷贝赋值功能相关函数&#xff08;覆盖&#xff09;2.1.1 strcpy2.1.2 strncpy2.1.3 memcpy2.1.4 memmove2.1.5 memset2.1.6 注意小点2.1.7 【函数区别】 2.2 追加功能相关函数2.2.1 strcat2.2.2 strnc…

使用plotly dash 画3d圆柱(Python)

plotly3D &#xff08;3d charts in Python&#xff09;可以画3维图形 在做圆柱的3D装箱项目&#xff0c;需要装箱的可视化&#xff0c;但是Mesh &#xff08;3d mesh plots in Python&#xff09;只能画三角形&#xff0c;所以需要用多个三角形拼成一个圆柱&#xff08;想做立…

Python qt.qpa.xcb: could not connect to display解决办法

遇到问题&#xff1a;qt.qpa.xcb: could not connect to display 解决办法&#xff0c;在命令行输入&#xff1a; export DISPLAY:0 然后重新跑python程序&#xff0c;解决&#xff01; 参考博客&#xff1a;qt.qpa.xcb: could not connect to displayqt.qpa.plugin: Could …

Ubuntu搭建国标平台wvp-GB28181-pro

目录 简介安装和编译1.查看操作系统信息2.安装最新版的nodejs3.安装java环境4.安装mysql5.安装redis6.安装编译器7.安装cmake8.安装依赖库9.编译ZLMediaKit9.1.编译结果说明 10.编译wvp-GB28181-pro10.1.编译结果说明 配置1.WVP-PRO配置文件1.1.Mysql数据库配置1.2.REDIS数据库…

监听项目中指定属性数据,点击或模块显示时

当项目中&#xff0c;需要获取某个页面上、某个标签上、有指定自定义属性时&#xff0c;需要在点击该元素时进行公共逻辑处理&#xff0c;或该元素在显示的时候进行逻辑处理&#xff0c;这时可以定义一个公共的方法&#xff0c;在每个页面引用&#xff0c;并写入数据即可 &…

OpenHarmony RK3568 启动流程优化

目前rk3568的开机时间有21s&#xff0c;统计的是关机后从按下 power 按键到显示锁屏的时间&#xff0c;当对openharmony的系统进行了裁剪子系统&#xff0c;系统app&#xff0c;禁用部分服务后发现开机时间仅仅提高到了20.94s 优化微乎其微。在对init进程的log进行分析并解决其…