在mvc模式中,消息机制被广泛使用,Unity3d自带的消息机制真心不好用,像SendMessage,需要知道响应事件的物件,还需要一个响应函数的函数名字符串作为参数,如果我们有多个物件都要响应某个事件怎么办呢,或者我们不知道有哪些物件要响应事件怎么办呢,在NEGUI的工具类NGUITools中有个函数NGUITools是这么实现的
- 静态 公共 无效 广播(字符串 了funcName)
- {
- 游戏对象[] GOS = GameObject.FindObjectsOfType(typeof运算(游戏对象)) 为 游戏对象[];
- 对于 (整数 I = 0,IMAX = gos.Length;我<IMAX; + I)GOS [I] SendMessage函数(了funcName,SendMessageOptions.DontRequireReceiver);
- }
- / / /公升; summarygt
- / / /调用在场景中的所有对象指定的函数。
- / / / </摘要>
- 静态 公共 无效 广播(字符串 了funcName, 对象 参数)
- {
- 游戏对象[] GOS = GameObject.FindObjectsOfType(typeof运算(游戏对象)) 为 游戏对象[];
- 对于 (整数 I = 0,IMAX = gos.Length;我<IMAX; + + i)条。GOS [I] SendMessage函数(了funcName,参数,SendMessageOptions.DontRequireReceiver);
- }
这似乎也满足我们的需求,但是,但是,如果我们的项目有一定的规模,GameObject有成千上万个,那么再遍历向所有的GameObject SendMessage函数就不那么现实了,所以我们需要新的实现方式。
本想自己写一个,但是百度了一下,发现早就有人实现了,所以在这里分享一下,原本地址点击这里,代码如下:
- 使用 UnityEngine;
- 使用 System.Collections;
- 使用 System.Collections.Generic;
- 使用 系统;
- / / NotificationCenter用于处理游戏物体之间的消息。
- / /游戏物体可以注册以接收特定的通知。当另一个对象发送该类型的通知,所有注册并落实相应的消息游戏物体将收到通知。
- / /五合一游戏物体必须注册才能获得与addObserver的功能的通知,并通过他们的自我,以及通知的名称。观察游戏物体也可以注销自己与RemoveObserver功能。游戏物体必须要求按类型基础上接收和删除一个类型的通知类型。
- / /发布通知是通过创建一个Notification对象并将它传递给PostNotification完成。所有接收游戏物体将接受通知的对象。通知对象包含发送者,通知类型名称,并包含数据的选项哈希表。
- / /要使用NotificationCenter,无论是创建和管理地方它唯一的实例,或者使用静态NotificationCenter。
- / /我们需要一个静态方法的对象能够获得默认的通知中心。
- / /这个默认的中心是所有的对象都将使用什么最通知。我们当然可以创建自己的独立NotificationCenter的实例,但这是静态的由所有。
- 公共 类 NotificationCenter:MonoBehaviour
- {
- 私有 静态 NotificationCenter defaultCenter;
- 公共 静态 NotificationCenter DefaultCenter(){
- / /如果defaultCenter不存在,我们需要创建它
- 如果 (!defaultCenter){
- / /因为NotificationCenter是一个组件,我们必须创建一个游戏物体将其附加到。
- 游戏物体notificationObject = 新的 游戏物体(“违约通知中心” );
- / /添加NotificationCenter组件,并将其设置为defaultCenter
- defaultCenter = notificationObject.AddComponent <NotificationCenter>();
- DontDestroyOnLoad(defaultCenter);
- }
- 返回 defaultCenter;
- }
- / /我们的散列表包含了所有的通知。在哈希表中的每个通知是包含所有的观察员该通知的ArrayList。
- Hashtable的通知= 新 的Hashtable();
- / / addObserver的包括版本,其中观察者可以从一个特定的对象要求只接收通知。我们还没有实现那个还,所以发送方的价值被忽略了。
- 公共 无效 的addObserver(组件观察员,字符串名称){的addObserver(观察员,名称, 空); }
- 公共 无效 的addObserver(组件观察员,字符串名称, 对象 发件人){
- / /如果名字不好,然后抛出一个错误并返回。
- 如果 (名称== 空 | |名== “” ){DEBUG.LOG( “ 通知中的addObserver指定空名称” ); 返回; }
- / /如果存在这个特定的通知还没有好好尝试一下,然后创建它。
- 如果 (!notifications.ContainsKey(名称)){
- 通知[名称] = 新 名单的<component>();
- }
- / /如果(!通知[名]){
- / /通知[名称] =新名单的<component>();
- / /}
- 名单的<component> notifyList =(列表的<component>)的通知[名称];
- / /如果观察员名单尚未包含了一个的注册,然后将其添加。
- 如果 {notifyList.Add(观察员)(notifyList.Contains(观察者)!); }
- }
- / / RemoveObserver删除观察者从通知列表中指定通知类型
- 公共 无效 RemoveObserver(组件观察员,字符串名称){
- 名单的<component> notifyList =(列表的<component>)的通知[名称] / /改变从原来的
- / /假设这是一个有效的通知类型,从列表中删除观察者。
- / /如果观察员名单现在是空的,然后从通知散列删除通知类型。这是看家的目的。
- 如果 (notifyList!= 空){
- 如果 (notifyList.Contains(观察者)){notifyList.Remove(观察者); }
- 如果 (notifyList.Count == 0){notifications.Remove(名); }
- }
- }
- / / PostNotification发送一个通知对象到已请求接收此类通知的所有对象。
- / /一个通知可以是贴有一个通知对象或只发送单个组件。
- 公共 无效 PostNotification(组件aSender,弦乐ANAME){PostNotification(aSender,ANAME, 空); }
- 公共 无效 PostNotification(组件aSender,弦乐ANAME, 反对 ADATA){PostNotification(新 通知(aSender,ANAME,ADATA)); }
- 公共 无效 PostNotification(通知aNotification){
- / /首先确保该通知的名称是有效的。
- 如果 (aNotification.name == 空 | | aNotification.name == “” ){DEBUG.LOG( “ 空名称发送到PostNotification”。); 回报; }
- / /获取通知列表,并确保它是有效的,以及
- 名单的<component> notifyList =(列表的<component>)的通知[aNotification.name] / /改变从原来的
- 如果 (notifyList == 空){DEBUG.LOG( “ 通知中PostNotification没有发现清单”。); 回报; }
- / /克隆列表中,所以不会有一个问题,如果一个观察者添加或删除,同时通知被发送
- notifyList = 新 名单的<component>(notifyList);
- / /创建一个数组来保存我们需要删除无效的观察员轨道
- 名单的<component> observersToRemove = 新 名单的<component>(); / /改变从原来的
- / / Itterate通过所有已签署了该类型的通知被通知的对象。
- 的foreach (组件观察员 在 notifyList){
- / /如果观察者是无效的,然后跟踪它,所以我们以后可以将其删除。
- / /我们无法将其删除,现在,还是会乱for循环起来。
- 如果 (观察员){observersToRemove.Add(观察者);
- } 否则 {
- / /如果观察者是有效的,然后发送该通知。这是发送的消息是通知的名称。
- observer.SendMessage(aNotification.name,aNotification,SendMessageOptions.DontRequireReceiver);
- }
- }
- / /删除所有无效的观察者
- 的foreach (组件观察员 在 observersToRemove){
- notifyList.Remove(观察者);
- }
- }
- }
- / /通知类是发送到接收通知类型的对象的对象。
- / /这个类包含发送游戏物体,该通知的名称,以及任选的含有哈希表的数据。
- 公共 类 {通知
- 公共 组件发送者;
- 公共 字符串名称;
- 公共 对象 数据;
- 公共 通知(组件aSender,弦乐ANAME){发件人= aSender; 名称= ANAME; 数据= 零; }
- 公共 通知(组件aSender,弦乐ANAME, 反对 ADATA){发件人= aSender; 名称= ANAME; 数据= ADATA; }
- }