当前位置:网站首页>Unity 消息框架 NotificationCenter

Unity 消息框架 NotificationCenter

2022-06-11 04:11:00 海 月

描述

通过 NotificationCenter 可以在 Unity 中的对象之间 实现消息传递。

当一个对象注册为观察者之后,如果某一事件发生,它将可以接收到通知,并执行相应的回调函数。当某种特定的通知,可以在任何地方,只要被推送,所有注册过该类型通知的观察者,都将收到通知。

有了这个消息系统,就可以方便地获取其他对象的状态,监听事件的发生,而不必困扰于怎么才能获取到其他对象的引用。一个对象推送一个消息,任何注册过的相关方,都可以接收到通知。

实际应用

比如,我有一个小怪组团。我希望玩家攻击任何一个小怪,组团内的前提小怪都要一起攻击玩家。我不希望保存所有小怪的引用,那样写的代码,耦合度太高。那么就可以使用消息机制来实现。

用法

这是一个自动实例化的单例类。它不挂载于任何的物体。把它放在工程文件中就可以使用。

具体的使用方法是通过获取单例的DefaultCenter函数。这个静态方法会自动创建游戏对象,然后添加一个通知中心组件,并且创建一个该组件的引用。

推送消息,使用 PostNotification 函数:

NotificationCenter.DefaultCenter().PostNotification(this, "OnReceiveMessage");
NotificationCenter.DefaultCenter().PostNotification(this, "OnReceiveMessage", anyObject);
NotificationCenter.DefaultCenter().PostNotification(new Notification(this, "OnReceiveMessage"));
NotificationCenter.DefaultCenter().PostNotification(new Notification(this, "OnReceiveMessage", anyObject));

PostNotification 函数有多种形式,它只需要两个参数:一个是消息的发送方,另一个是消息推送的关键字。可以选择传送各种各样的数据对象,它可以是任何需要传送的数据。

PostNotification 函数可以 以两种形式被调用,一种是独立的参数,一种是传递一个通知对象。

通知对象是一个类,包含了通知是相关信息,比如发送方、关键字、以及可选的数据对象。

通过调用 AddObserver 函数 注册观察者:

NotificationCenter.DefaultCenter().AddObserver(this, "OnReceiveMessage");

DefaultCenter 函数是一个静态方法,返回的是默认通知中心的实例。如果它不存在,则会被默认实例化。AddObserver 函数同样可以接收两个参数,一个是需要接收通知的对象,一个是需要接收的通知的关键字。当一个通知被推送,且注册过该类型通知的观察者接收到了该通知时,回调函数将被执行。

使用 RemoveObserver 函数移除观察者:

NotificationCenter.DefaultCenter().RemoveObserver(this, "OnReceiveMessage");

RemoveObserver 函数 将会接触该对象对某一特定通知的监听。

需要接收通知,要用通知的关键字实现一个回调函数。

void OnReceiveMessage(Notification notification)
{
    Debug.Log("Received notification from: " + notification.sender);
    if (notification.data == null)
        Debug.Log("And the data object was null!");
    else
        Debug.Log("And it included a data object: " + notification.data);
}

回调函数必须接收通知对象,它包含三个属性,分别是发送者、关键字、可选的数据。

代码

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class NotificationCenter : MonoBehaviour
{
	private static NotificationCenter defaultCenter;
	public static NotificationCenter DefaultCenter()
	{
		if (!defaultCenter)
		{
			GameObject notificationObject = new GameObject("Default Notification Center");
			defaultCenter = notificationObject.AddComponent<NotificationCenter>();
			DontDestroyOnLoad(defaultCenter);
		}

		return defaultCenter;
	}

	Hashtable notifications = new Hashtable();

	public void AddObserver(Component observer, String name) { AddObserver(observer, name, null); }
	public void AddObserver(Component observer, String name, object sender)
	{
		if (name == null || name == "") { Debug.Log("Null name specified for notification in AddObserver."); return; }

		if (!notifications.ContainsKey(name))
		{
			notifications[name] = new List<Component>();
		}

		List<Component> notifyList = (List<Component>)notifications[name];

		if (!notifyList.Contains(observer)) { notifyList.Add(observer); }
	}

	public void RemoveObserver(Component observer, String name)
	{
		List<Component> notifyList = (List<Component>)notifications[name]; 

		if (notifyList != null)
		{
			if (notifyList.Contains(observer)) { notifyList.Remove(observer); }
			if (notifyList.Count == 0) { notifications.Remove(name); }
		}
	}

	public void PostNotification(Component aSender, String aName) { PostNotification(aSender, aName, null); }
	public void PostNotification(Component aSender, String aName, object aData) { PostNotification(new Notification(aSender, aName, aData)); }
	public void PostNotification(Notification aNotification)
	{
		if (aNotification.name == null || aNotification.name == "") { Debug.Log("Null name sent to PostNotification."); return; }

		List<Component> notifyList = (List<Component>)notifications[aNotification.name]; 
		if (notifyList == null) { Debug.Log("Notify list not found in PostNotification."); return; }

		notifyList = new List<Component>(notifyList);

		List<Component> observersToRemove = new List<Component>(); 

		foreach (Component observer in notifyList)
		{
			if (!observer)
			{
				observersToRemove.Add(observer);
			}
			else
			{
				observer.SendMessage(aNotification.name, aNotification, SendMessageOptions.DontRequireReceiver);
			}
		}

		foreach (Component observer in observersToRemove)
		{
			notifyList.Remove(observer);
		}
	}
}

public class Notification
{
	public Component sender;
	public String name;
	public object data;

	public Notification(Component aSender, String aName) { sender = aSender; name = aName; data = null; }
	public Notification(Component aSender, String aName, object aData) { sender = aSender; name = aName; data = aData; }
}

翻译自

http://wiki.unity3d.com/index.php/NotificationCenterGenerics

作者 : capnbishop

更新 : chrisg, Marcus_Mattsson

原网站

版权声明
本文为[海 月]所创,转载请带上原文链接,感谢
https://haiyue.blog.csdn.net/article/details/124319969