Unity消息机制

在mvc模式中,消息机制被广泛使用,Unity3d自带的消息机制真心不好用,像 SendMessage,需要知道响应事件的物件,还需要一个响应函数的函数名字符串作为参数,如果我们有多个物件都要响应某个事件怎么办呢,或者我们不知道有哪些物件要响应事件怎么办呢,在NEGUI的工具类NGUITools中有个函数NGUITools是这么实现的

  1. static public void Broadcast (string funcName)  
  2. {  
  3.     GameObject[] gos = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[];  
  4.     for (int i = 0, imax = gos.Length; i < imax; ++i) gos[i].SendMessage(funcName, SendMessageOptions.DontRequireReceiver);  
  5. }  
  6.   
  7. /// <summary>  
  8. /// Call the specified function on all objects in the scene.  
  9. /// </summary>  
  10.   
  11. static public void Broadcast (string funcName, object param)  
  12. {  
  13.     GameObject[] gos = GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[];  
  14.     for (int i = 0, imax = gos.Length; i < imax; ++i) gos[i].SendMessage(funcName, param, SendMessageOptions.DontRequireReceiver);  
  15. }  

这似乎也满足我们的需求,但是,但是,如果我们的项目有一定的规模,GameObject有成千上万个,那么再遍历向所有的GameObject SendMessage就不那么现实了,所以我们需要新的实现方式。

本想自己写一个,但是百度了一下,发现早就有人实现了,所以在这里分享一下,原本地址点击这里,代码如下:

  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using System;  
  5.    
  6. //    NotificationCenter is used for handling messages between GameObjects.  
  7. //    GameObjects can register to receive specific notifications.  When another objects sends a notification of that type, all GameObjects that registered for it and implement the appropriate message will receive that notification.  
  8. //    Observing GameObjects must register to receive notifications with the AddObserver function, and pass their selves, and the name of the notification.  Observing GameObjects can also unregister themselves with the RemoveObserver function.  GameObjects must request to receive and remove notification types on a type by type basis.  
  9. //    Posting notifications is done by creating a Notification object and passing it to PostNotification.  All receiving GameObjects will accept that Notification object.  The Notification object contains the sender, the notification type name, and an option hashtable containing data.  
  10. //    To use NotificationCenter, either create and manage a unique instance of it somewhere, or use the static NotificationCenter.  
  11.    
  12. // We need a static method for objects to be able to obtain the default notification center.  
  13. // This default center is what all objects will use for most notifications.  We can of course create our own separate instances of NotificationCenter, but this is the static one used by all.  
  14. public class NotificationCenter : MonoBehaviour  
  15. {  
  16.     private static NotificationCenter defaultCenter;  
  17.     public static NotificationCenter DefaultCenter () {  
  18.         // If the defaultCenter doesn't already exist, we need to create it  
  19.         if (!defaultCenter) {  
  20.             // Because the NotificationCenter is a component, we have to create a GameObject to attach it to.  
  21.             GameObject notificationObject = new GameObject("Default Notification Center");  
  22.             // Add the NotificationCenter component, and set it as the defaultCenter  
  23.             defaultCenter = notificationObject.AddComponent<NotificationCenter>();  
  24.         DontDestroyOnLoad(notificationObject);  
  25.         }  
  26.    
  27.         return defaultCenter;  
  28.     }  
  29.    
  30.     // Our hashtable containing all the notifications.  Each notification in the hash table is an ArrayList that contains all the observers for that notification.  
  31.     Hashtable notifications = new Hashtable();  
  32.    
  33.     // AddObserver includes a version where the observer can request to only receive notifications from a specific object.  We haven't implemented that yet, so the sender value is ignored for now.  
  34.     public void AddObserver (Component observer, String name) { AddObserver(observer, name, null); }  
  35.     public void AddObserver (Component observer, String name, object sender) {  
  36.         // If the name isn't good, then throw an error and return.  
  37.         if (name == null || name == "") { Debug.Log("Null name specified for notification in AddObserver."); return; }  
  38.         // If this specific notification doens't exist yet, then create it.  
  39.         if (!notifications.ContainsKey(name)) {  
  40.             notifications[name] = new List<Component>();  
  41.         }  
  42. //      if (!notifications[name]) {  
  43. //          notifications[name] = new List<Component>();  
  44. //      }  
  45.    
  46.         List<Component> notifyList = (List<Component>)notifications[name];  
  47.    
  48.         // If the list of observers doesn't already contain the one that's registering, then add it.  
  49.         if (!notifyList.Contains(observer)) { notifyList.Add(observer); }  
  50.     }  
  51.    
  52.     // RemoveObserver removes the observer from the notification list for the specified notification type  
  53.     public void RemoveObserver (Component observer, String name) {  
  54.         List<Component> notifyList = (List<Component>)notifications[name]; //change from original  
  55.    
  56.         // Assuming that this is a valid notification type, remove the observer from the list.  
  57.         // If the list of observers is now empty, then remove that notification type from the notifications hash.  This is for housekeeping purposes.  
  58.         if (notifyList != null) {  
  59.             if (notifyList.Contains(observer)) { notifyList.Remove(observer); }  
  60.             if (notifyList.Count == 0) { notifications.Remove(name); }  
  61.         }  
  62.     }  
  63.    
  64.     // PostNotification sends a notification object to all objects that have requested to receive this type of notification.  
  65.     // A notification can either be posted with a notification object or by just sending the individual components.  
  66.     public void PostNotification (Component aSender, String aName) { PostNotification(aSender, aName, null); }  
  67.     public void PostNotification (Component aSender, String aName, object aData) { PostNotification(new Notification(aSender, aName, aData)); }  
  68.     public void PostNotification (Notification aNotification) {  
  69.         // First make sure that the name of the notification is valid.  
  70.         if (aNotification.name == null || aNotification.name == "") { Debug.Log("Null name sent to PostNotification."); return; }  
  71.         // Obtain the notification list, and make sure that it is valid as well  
  72.         List<Component> notifyList = (List<Component>)notifications[aNotification.name]; //change from original  
  73.         if (notifyList == null) { Debug.Log("Notify list not found in PostNotification."); return; }  
  74.    
  75.         // Clone list, so there won't be an issue if an observer is added or removed while notifications are being sent  
  76.         notifyList = new List<Component>(notifyList);  
  77.    
  78.         // Create an array to keep track of invalid observers that we need to remove  
  79.         List<Component> observersToRemove = new List<Component>(); //change from original  
  80.    
  81.         // Itterate through all the objects that have signed up to be notified by this type of notification.  
  82.         foreach (Component observer in notifyList) {  
  83.             // If the observer isn't valid, then keep track of it so we can remove it later.  
  84.             // We can't remove it right now, or it will mess the for loop up.  
  85.             if (!observer) { observersToRemove.Add(observer);  
  86.             } else {  
  87.                 // If the observer is valid, then send it the notification.  The message that's sent is the name of the notification.  
  88.                 observer.SendMessage(aNotification.name, aNotification, SendMessageOptions.DontRequireReceiver);  
  89.             }  
  90.         }  
  91.    
  92.         // Remove all the invalid observers  
  93.         foreach (Component observer in observersToRemove) {  
  94.             notifyList.Remove(observer);  
  95.         }  
  96.     }  
  97. }  
  98.    
  99. // The Notification class is the object that is sent to receiving objects of a notification type.  
  100. // This class contains the sending GameObject, the name of the notification, and optionally a hashtable containing data.  
  101. public class Notification {  
  102.     public Component sender;  
  103.     public String name;  
  104.     public object data;  
  105.    
  106.     public Notification (Component aSender, String aName) { sender = aSender; name = aName; data = null; }  
  107.     public Notification (Component aSender, String aName, object aData) { sender = aSender; name = aName; data = aData; }  
  108. }  
看完这段代码,相信你已经知道该怎么用了!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值