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
1
public
delegate
void
Callback();
2
public
delegate
void
Callback<T>(T arg1);
3
public
delegate
void
Callback<T, U>(T arg1, U arg2);
4
public
delegate
void
Callback<T, U, V>(T arg1, U arg2, V arg3);
Message.cs
026
#define REQUIRE_LISTENER
029
using
System.Collections.Generic;
032
static
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);
296
public
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表示广播所调用的方法。
02
using
System.Collections;
04
public
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);
然后是接受的地方 参数用<>存在一起。游戏对象也可以完美的传递。
02
using
System.Collections;
04
public
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>
怎么样使用起来还是挺简单的吧?