Advanced CSharp Messenger的特点可以将游戏对象做为参数发送。到底Advanced CSharp Messenger有什么用呢?先创建一个立方体对象,然后把Script脚本绑定在这个对象中。脚本中有一个方法叫DoSomething()。 写一段简单的代码,通常我们在调用方法的时候需要这样来写。
04 GameObject cube = GameObject.Find("Cube");
05 script = cube.GetComponent<Script>();
09 if(Input.GetMouseButtonDown(0))
代码比较简单,我就不注释了。 原理就是先获取游戏对象,接着获取脚本组件对象,最后通过脚本组件对象去调用对应脚本中的方法,这样的调用方法我们称之为直接调用。
这个例子中我只调用了一个对象的方法,如果说有成千上万个对象,那么这样调用是不是感觉自己的代码非常的丑?因为你需要一个一个的获取对象然后获取脚本组件然后在调用方法。。。。。 (想想都恐怖!!)
下面我们在用Advanced CSharp Messenger来实现事件的调用。按照维基百科中首先把Message.cs 和Callback.cs拷贝在你的工程中。
CallBack.cs
1public delegate void Callback();
2public delegate void Callback<T>(T arg1);
3public delegate void Callback<T, U>(T arg1, U arg2);
4public delegate void Callback<T, U, V>(T arg1, U arg2, V arg3);
Message.cs
026#define REQUIRE_LISTENER
029using System.Collections.Generic;
032static internal class Messenger {
033 #region Internal variables
036#pragma warning disable 0414
038 static private MessengerHelper messengerHelper = ( new GameObject("MessengerHelper") ).AddComponent< MessengerHelper >();
039#pragma warning restore 0414
041 static public Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
044 static public List< string > permanentMessages = new List< string > ();
046 #region Helper methods
048 static public void MarkAsPermanent(string eventType) {
050 Debug.Log("Messenger MarkAsPermanent \t\"" + eventType + "\"");
053 permanentMessages.Add( eventType );
056 static public void Cleanup()
059 Debug.Log("MESSENGER Cleanup. Make sure that none of necessary listeners are removed.");
062 List< string > messagesToRemove = new List<string>();
064 foreach (KeyValuePair<string, Delegate> pair in eventTable) {
065 bool wasFound = false;
067 foreach (string message in permanentMessages) {
068 if (pair.Key == message) {
075 messagesToRemove.Add( pair.Key );
078 foreach (string message in messagesToRemove) {
079 eventTable.Remove( message );
083 static public void PrintEventTable()
085 Debug.Log("\t\t\t=== MESSENGER PrintEventTable ===");
087 foreach (KeyValuePair<string, Delegate> pair in eventTable) {
088 Debug.Log("\t\t\t" + pair.Key + "\t\t" + pair.Value);
095 #region Message logging and exception throwing
096 static public void OnListenerAdding(string eventType, Delegate listenerBeingAdded) {
097#if LOG_ALL_MESSAGES || LOG_ADD_LISTENER
098 Debug.Log("MESSENGER OnListenerAdding \t\"" + eventType + "\"\t{" + listenerBeingAdded.Target + " -> " + listenerBeingAdded.Method + "}");
101 if (!eventTable.ContainsKey(eventType)) {
102 eventTable.Add(eventType, null );
105 Delegate d = eventTable[eventType];
106 if (d != null && d.GetType() != listenerBeingAdded.GetType()) {
107 throw new ListenerException(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", eventType, d.GetType().Name, listenerBeingAdded.GetType().Name));
111 static public void OnListenerRemoving(string eventType, Delegate listenerBeingRemoved) {
113 Debug.Log("MESSENGER OnListenerRemoving \t\"" + eventType + "\"\t{" + listenerBeingRemoved.Target + " -> " + listenerBeingRemoved.Method + "}");
116 if (eventTable.ContainsKey(eventType)) {
117 Delegate d = eventTable[eventType];
120 throw new ListenerException(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", eventType));
121 } else if (d.GetType() != listenerBeingRemoved.GetType()) {
122 throw new ListenerException(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", eventType, d.GetType().Name, listenerBeingRemoved.GetType().Name));
125 throw new ListenerException(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", eventType));
129 static public void OnListenerRemoved(string eventType) {
130 if (eventTable[eventType] == null) {
131 eventTable.Remove(eventType);
135 static public void OnBroadcasting(string eventType) {
137 if (!eventTable.ContainsKey(eventType)) {
138 throw new BroadcastException(string.Format("Broadcasting message \"{0}\" but no listener found. Try marking the message with Messenger.MarkAsPermanent.", eventType));
143 static public BroadcastException CreateBroadcastSignatureException(string eventType) {
144 return new BroadcastException(string.Format("Broadcasting message \"{0}\" but listeners have a different signature than the broadcaster.", eventType));
147 public class BroadcastException : Exception {
148 public BroadcastException(string msg)
153 public class ListenerException : Exception {
154 public ListenerException(string msg)
162 static public void AddListener(string eventType, Callback handler) {
163 OnListenerAdding(eventType, handler);
164 eventTable[eventType] = (Callback)eventTable[eventType] + handler;
168 static public void AddListener<T>(string eventType, Callback<T> handler) {
169 OnListenerAdding(eventType, handler);
170 eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
174 static public void AddListener<T, U>(string eventType, Callback<T, U> handler) {
175 OnListenerAdding(eventType, handler);
176 eventTable[eventType] = (Callback<T, U>)eventTable[eventType] + handler;
180 static public void AddListener<T, U, V>(string eventType, Callback<T, U, V> handler) {
181 OnListenerAdding(eventType, handler);
182 eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] + handler;
186 #region RemoveListener
188 static public void RemoveListener(string eventType, Callback handler) {
189 OnListenerRemoving(eventType, handler);
190 eventTable[eventType] = (Callback)eventTable[eventType] - handler;
191 OnListenerRemoved(eventType);
195 static public void RemoveListener<T>(string eventType, Callback<T> handler) {
196 OnListenerRemoving(eventType, handler);
197 eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler;
198 OnListenerRemoved(eventType);
202 static public void RemoveListener<T, U>(string eventType, Callback<T, U> handler) {
203 OnListenerRemoving(eventType, handler);
204 eventTable[eventType] = (Callback<T, U>)eventTable[eventType] - handler;
205 OnListenerRemoved(eventType);
209 static public void RemoveListener<T, U, V>(string eventType, Callback<T, U, V> handler) {
210 OnListenerRemoving(eventType, handler);
211 eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] - handler;
212 OnListenerRemoved(eventType);
218 static public void Broadcast(string eventType) {
219#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
220 Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
222 OnBroadcasting(eventType);
225 if (eventTable.TryGetValue(eventType, out d)) {
226 Callback callback = d as Callback;
228 if (callback != null) {
231 throw CreateBroadcastSignatureException(eventType);
237 static public void Broadcast<T>(string eventType, T arg1) {
238#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
239 Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
241 OnBroadcasting(eventType);
244 if (eventTable.TryGetValue(eventType, out d)) {
245 Callback<T> callback = d as Callback<T>;
247 if (callback != null) {
250 throw CreateBroadcastSignatureException(eventType);
256 static public void Broadcast<T, U>(string eventType, T arg1, U arg2) {
257#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
258 Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
260 OnBroadcasting(eventType);
263 if (eventTable.TryGetValue(eventType, out d)) {
264 Callback<T, U> callback = d as Callback<T, U>;
266 if (callback != null) {
267 callback(arg1, arg2);
269 throw CreateBroadcastSignatureException(eventType);
275 static public void Broadcast<T, U, V>(string eventType, T arg1, U arg2, V arg3) {
276#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
277 Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
279 OnBroadcasting(eventType);
282 if (eventTable.TryGetValue(eventType, out d)) {
283 Callback<T, U, V> callback = d as Callback<T, U, V>;
285 if (callback != null) {
286 callback(arg1, arg2, arg3);
288 throw CreateBroadcastSignatureException(eventType);
296public sealed class MessengerHelper : MonoBehaviour {
299 DontDestroyOnLoad(gameObject);
303 public void OnDisable() {
然后就可以开始使用了,Messager.Broadcast()这样就好比我们发送了一条广播。
3 if(Input.GetMouseButtonDown(0))
5 Messenger.Broadcast("Send");
在需要这条广播的类中来接受它,同样是刚刚说的Script类。接受广播的标志是 Messager.AddListener()参数1表示广播的名称,参数2表示广播所调用的方法。
02using System.Collections;
04public class Script : MonoBehaviour {
08 Messenger.AddListener( "Send", DoSomething );
10 public void DoSomething()
12 Debug.Log("DoSomething");
这样一来,只要发送名称为”Send”的方法,就可以在别的类中接收它了。
我们在说说如何通过广播来传递参数,这也是那天那个哥们主要问我的问题。(其实是维基百科上写的不是特别特别的清楚,那哥们误解了)在Callback中可以看出参数最多可以是三个,参数的类型是任意类型,也就是说我们不仅能传递 int float bool 还能传递gameObject类型。
如下所示,发送广播的时候传递了两个参数,参数1是一个游戏对象,参数2是一个int数值。
3 if(Input.GetMouseButtonDown(0))
5 GameObject cube = GameObject.Find("Cube");
6 Messenger.Broadcast<GameObject,int>("Send",cube,1980);
然后是接受的地方 参数用<>存在一起。游戏对象也可以完美的传递。
02using System.Collections;
04public class Script : MonoBehaviour {
08 Messenger.AddListener<GameObject,int>( "Send", DoSomething );
10 public void DoSomething(GameObject obj,int i)
12 Debug.Log("name " + obj.name + " id =" + i);
如果传递一个参数<T>
两个参数<T,T>
三个参数<T,T,T>
怎么样使用起来还是挺简单的吧?