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.hqwc.cn/news/441159.html

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

相关文章

【Linux】vim的简单使用

我们知道在Windows下的VS2019是一个集成开发环境&#xff0c;也就是说&#xff0c;集编辑&#xff0c;编译&#xff0c;调试等功能都放在了一起&#xff1b;但是在Linux下&#xff0c;这些步骤都是分开的&#xff0c;我们这篇博客就来说一说vim这个编辑器&#xff0c;它只有编辑…

HarmonyOS 鸿蒙驱动消息机制管理

驱动消息机制管理 使用场景 当用户态应用和内核态驱动需要交互时&#xff0c;可以使用HDF框架的消息机制来实现。 接口说明 消息机制的功能主要有以下两种&#xff1a; 用户态应用发送消息到驱动。 用户态应用接收驱动主动上报事件。 表1 消息机制接口 方法描述struct …

父元素flex:1 高度却被子元素撑开的问题

问题 当父元素设置了flex: 1; 的情况下&#xff0c;想在其中子元素超出父元素高度的情况下&#xff0c;产生滚动条&#xff0c;在父元素区域滚动。由于子元素高度不固定&#xff0c;故父元素设置为display: flex; flex-direction: column; 子元素设置flex: 1; overflow: auto;…

【pytest系列】- assert断言的使用

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

LabVIEW电液伺服控制系统

介绍了如何利用ARM微处理器和LabVIEW软件开发一个高效、精准的电液伺服控制系统。通过结合这两种技术&#xff0c;我们能够提高系统的数字化程度、集成化水平&#xff0c;以及控制精度&#xff0c;从而应对传统电液伺服控制器面临的问题。 该电液伺服控制系统由多个关键部分组…

实战项目(二)汽车保养管家系统

一、实现技术 前端技术&#xff1a;html、javascript(jquery、ajax、json)、css、layui 后端技术&#xff1a;java、mysql、servlet 开发工具&#xff1a;eclipse、vscode 二、项目描述 基于web的汽车保养管家系统的设计与实现 一、功能需求 1&#xff0e;用户功能 1.1…

Android中属性property_get和property_set的详细用法介绍

1&#xff0c;property_get和property_set的作用说明 在Android操作系统中&#xff0c;property_get和property_set是用于获取和设置系统属性的函数。这些属性通常用于存储和读取配置信息&#xff0c;例如设备配置、网络设置、系统参数等。 property_get函数用于获取指定属性…

Netty源码三:NioEventLoop创建与run方法

1.入口 会调用到父类SingleThreadEventLoop的构造方法 2.SingleThreadEventLoop 继续调用父类SingleThreadEventExecutor的构造方法 3.SingleThreadEventExecutor 到这里完整的总结一下&#xff1a; 将线程执行器保存到每一个SingleThreadEventExcutor里面去创建了MpscQu…

Windows断开映射磁盘提示“此网络连接不存在”,并且该磁盘直在资源管理器中

1、打开注册表编辑器 快捷键winR 打开“运行”&#xff0c; 输入 regedit 2、 删除下列注册表中和无法移除的磁盘相关的选项 \HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\ 3、打开“任务管理器”&#xff0c;重新启动“Windows资源…

微信扫码登录流程

微信官方文档使用 搜索“微信开放平台”点击导航栏的“资源中心”点击“网站应用”下的“微信登录功能”地址微信扫码登录是基于OAuth2的&#xff0c;所以需要第三方应用&#xff08;就是实现微信扫码登录的应用&#xff09;成为微信的客户端&#xff0c;获取AppId和AppSecret…

用AI工具一键生成原创文案的方法

一键生成原创文案对于文案工作者来说它是一种高效率创作文案内容的方法。文案工作者知道创作文案是一件消耗精力和时间的事情&#xff0c;遇到没有创作灵感&#xff0c;想要写一篇高质量的文案内容简直难上加难&#xff0c;因此&#xff0c;互联网上出现了一键生成原创文案的方…

漏洞原理文件上传漏洞

一 文件上传漏洞介绍&#xff08;理论&#xff09; 文件上传漏洞是一种常见的web应用程序漏洞&#xff0c;允许攻击者向服务器上传恶意文件。这种漏洞可在没有恰当的安全措施的情况下&#xff0c;将任意类型的文件上传到服务器上&#xff0c;从而可能导致以下安全问题&#xff…