再用unity进行开发过程中,不可避免的用到消息的传递问题,以下介绍几种消息传递的方法:

(一)拖动赋值

此方法即为最普通的方法,即把需要引用的游戏物体或者需要引用的组件拖动到相关公有变量的槽上,然后就可以引用相关变量或者方法,继而可以进行消息的传递。也可以用Find方法查找到相关游戏物体,然后获取相关组件以及组件上的方法,变量。

(二)采用unity GameObject自带的公用方法

1)public void BroadcastMessage(string methodName, object parameter , SendMessageOptions options)

此方法为调用其本身以及子游戏物体上名为methodName的同名方法,其中parameter 为methodName方法所需要的参数,此方法可以理解为向下发送消息,即向本身以及子游戏物体发送消息

2)public void SendMessage(string methodName, object valuel, SendMessageOptions options)

此方法为调用其本身游戏物体上名为methodName的同名方法,其中parameter 为methodName方法所需要的参数,此方法为平行发送消息。

3)public void SendMessageUpwards(string methodName, object value, SendMessageOptions options)

此方法为调用其本身以及父类游戏物体上名为methodName的同名方法,其中parameter 为methodName方法所需要的参数,此方法为向上发送消息。

(三)向任意位置发送消息

以上介绍的两种方法都有一定的局限性,在此介绍一种简单的方法,在此需要两个cs文件,分别为Messenger.cs与Callback.cs,相关代码会在后续中给出。通过以下方法进行调用:

        Messenger.AddListener("Method1", OnClicked);//将OnClicked方法绑定到"Method1"上
Messenger.Broadcast("Method1");//通过"Method1"调用方法将OnClicked方法绑定到
Messenger.RemoveListener("Method1", OnClicked);//将OnClicked方法从"Method1"移除

泛型方法如下:

        Messenger.AddListener<string>("Method1", OnClicked);//将OnClicked方法绑定到"Method1"上
Messenger.Broadcast<string>("Method1","name");//通过"Method1"调用方法将OnClicked方法绑定到
Messenger.RemoveListener<string>("Method1", OnClicked);//将OnClicked方法从"Method1"移除

不过此方法效率很低,不可滥用

(四)通过C#委托

通过C#多播委托可以实现精准消息传递,而且方便快捷,但是要求对中间细节把控较高,尤其是要在适当的位置解除方法绑定

附录

Messenger.cs

/*
* Advanced C# messenger by Ilya Suzdalnitski. V1.0
*
* Based on Rod Hyde's "CSharpMessenger" and Magnus Wolffelt's "CSharpMessenger Extended".
*
* Features:
* Prevents a MissingReferenceException because of a reference to a destroyed message handler.
* Option to log all messages
* Extensive error detection, preventing silent bugs
*
* Usage examples:
1. Messenger.AddListener<GameObject>("prop collected", PropCollected);
Messenger.Broadcast<GameObject>("prop collected", prop);
2. Messenger.AddListener<float>("speed changed", SpeedChanged);
Messenger.Broadcast<float>("speed changed", 0.5f);
*
* Messenger cleans up its evenTable automatically upon loading of a new level.
*
* Don't forget that the messages that should survive the cleanup, should be marked with Messenger.MarkAsPermanent(string)
*
*/ //#define LOG_ALL_MESSAGES
//#define LOG_ADD_LISTENER
//#define LOG_BROADCAST_MESSAGE
#define REQUIRE_LISTENER using System;
using System.Collections.Generic;
using UnityEngine; static internal class Messenger
{
#region Internal variables //Disable the unused variable warning
#pragma warning disable 0414
//Ensures that the MessengerHelper will be created automatically upon start of the game.
static private MessengerHelper messengerHelper = (new GameObject("MessengerHelper")).AddComponent<MessengerHelper>();
#pragma warning restore 0414 static public Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>(); //Message handlers that should never be removed, regardless of calling Cleanup
static public List<string> permanentMessages = new List<string>();
#endregion
#region Helper methods
//Marks a certain message as permanent.
static public void MarkAsPermanent(string eventType)
{
#if LOG_ALL_MESSAGES
Debug.Log("Messenger MarkAsPermanent \t\"" + eventType + "\"");
#endif permanentMessages.Add(eventType);
} static public void Cleanup()
{
#if LOG_ALL_MESSAGES
Debug.Log("MESSENGER Cleanup. Make sure that none of necessary listeners are removed.");
#endif List<string> messagesToRemove = new List<string>(); foreach (KeyValuePair<string, Delegate> pair in eventTable)
{
bool wasFound = false; foreach (string message in permanentMessages)
{
if (pair.Key == message)
{
wasFound = true;
break;
}
} if (!wasFound)
messagesToRemove.Add(pair.Key);
} foreach (string message in messagesToRemove)
{
eventTable.Remove(message);
}
} static public void PrintEventTable()
{
Debug.Log("\t\t\t=== MESSENGER PrintEventTable ==="); foreach (KeyValuePair<string, Delegate> pair in eventTable)
{
Debug.Log("\t\t\t" + pair.Key + "\t\t" + pair.Value);
} Debug.Log("\n");
}
#endregion #region Message logging and exception throwing
static public void OnListenerAdding(string eventType, Delegate listenerBeingAdded)
{
#if LOG_ALL_MESSAGES || LOG_ADD_LISTENER
Debug.Log("MESSENGER OnListenerAdding \t\"" + eventType + "\"\t{" + listenerBeingAdded.Target + " -> " + listenerBeingAdded.Method + "}");
#endif if (!eventTable.ContainsKey(eventType))
{
eventTable.Add(eventType, null);
} Delegate d = eventTable[eventType];
if (d != null && d.GetType() != listenerBeingAdded.GetType())
{
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));
}
} static public void OnListenerRemoving(string eventType, Delegate listenerBeingRemoved)
{
#if LOG_ALL_MESSAGES
Debug.Log("MESSENGER OnListenerRemoving \t\"" + eventType + "\"\t{" + listenerBeingRemoved.Target + " -> " + listenerBeingRemoved.Method + "}");
#endif if (eventTable.ContainsKey(eventType))
{
Delegate d = eventTable[eventType]; if (d == null)
{
throw new ListenerException(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", eventType));
}
else if (d.GetType() != listenerBeingRemoved.GetType())
{
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));
}
}
else
{
throw new ListenerException(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", eventType));
}
} static public void OnListenerRemoved(string eventType)
{
if (eventTable[eventType] == null)
{
eventTable.Remove(eventType);
}
} static public void OnBroadcasting(string eventType)
{
#if REQUIRE_LISTENER
if (!eventTable.ContainsKey(eventType))
{
throw new BroadcastException(string.Format("Broadcasting message \"{0}\" but no listener found. Try marking the message with Messenger.MarkAsPermanent.", eventType));
}
#endif
} static public BroadcastException CreateBroadcastSignatureException(string eventType)
{
return new BroadcastException(string.Format("Broadcasting message \"{0}\" but listeners have a different signature than the broadcaster.", eventType));
} public class BroadcastException : Exception
{
public BroadcastException(string msg)
: base(msg)
{
}
} public class ListenerException : Exception
{
public ListenerException(string msg)
: base(msg)
{
}
}
#endregion #region AddListener
//No parameters
static public void AddListener(string eventType, Callback handler)
{
OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback)eventTable[eventType] + handler;
} //Single parameter
static public void AddListener<T>(string eventType, Callback<T> handler)
{
OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
} //Two parameters
static public void AddListener<T, U>(string eventType, Callback<T, U> handler)
{
OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U>)eventTable[eventType] + handler;
} //Three parameters
static public void AddListener<T, U, V>(string eventType, Callback<T, U, V> handler)
{
OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] + handler;
}
#endregion #region RemoveListener
//No parameters
static public void RemoveListener(string eventType, Callback handler)
{
OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback)eventTable[eventType] - handler;
OnListenerRemoved(eventType);
} //Single parameter
static public void RemoveListener<T>(string eventType, Callback<T> handler)
{
OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler;
OnListenerRemoved(eventType);
} //Two parameters
static public void RemoveListener<T, U>(string eventType, Callback<T, U> handler)
{
OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U>)eventTable[eventType] - handler;
OnListenerRemoved(eventType);
} //Three parameters
static public void RemoveListener<T, U, V>(string eventType, Callback<T, U, V> handler)
{
OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] - handler;
OnListenerRemoved(eventType);
}
#endregion #region Broadcast
//No parameters
static public void Broadcast(string eventType)
{
#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
#endif
OnBroadcasting(eventType); Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback callback = d as Callback; if (callback != null)
{
callback();
}
else
{
throw CreateBroadcastSignatureException(eventType);
}
}
} //Single parameter
static public void Broadcast<T>(string eventType, T arg1)
{
#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
#endif
OnBroadcasting(eventType); Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T> callback = d as Callback<T>; if (callback != null)
{
callback(arg1);
}
else
{
throw CreateBroadcastSignatureException(eventType);
}
}
} //Two parameters
static public void Broadcast<T, U>(string eventType, T arg1, U arg2)
{
#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
#endif
OnBroadcasting(eventType); Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U> callback = d as Callback<T, U>; if (callback != null)
{
callback(arg1, arg2);
}
else
{
throw CreateBroadcastSignatureException(eventType);
}
}
} //Three parameters
static public void Broadcast<T, U, V>(string eventType, T arg1, U arg2, V arg3)
{
#if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
#endif
OnBroadcasting(eventType); Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T, U, V> callback = d as Callback<T, U, V>; if (callback != null)
{
callback(arg1, arg2, arg3);
}
else
{
throw CreateBroadcastSignatureException(eventType);
}
}
}
#endregion
} //This manager will ensure that the messenger's eventTable will be cleaned up upon loading of a new level.
public sealed class MessengerHelper : MonoBehaviour
{
void Awake()
{
DontDestroyOnLoad(gameObject);
} //Clean up eventTable every time a new level loads.
public void OnDisable()
{
Messenger.Cleanup();
}
}

Callback.cs

public delegate void Callback();
public delegate void Callback<T>(T arg1);
public delegate void Callback<T, U>(T arg1, U arg2);
public delegate void Callback<T, U, V>(T arg1, U arg2, V arg3);

最新文章

  1. String... 用法
  2. FFMpeg ver 20160213-git-588e2e3 滤镜中英文对照
  3. Oracle导入dmp备份文件到不同的表空间中
  4. 【暑假】[深入动态规划]UVa 10618 Fun Game
  5. Word添加带圈文字
  6. [置顶] Guava学习之Splitter
  7. android程序启动画面之Splash总结[转]
  8. StackExchange.Redis 使用 (一)
  9. Git@OSC &amp; SSH配置
  10. React Native热更新(iOS)-Pushy
  11. Harbor配置https认证
  12. 个人 git-hub使用方法
  13. sqlserver数据库知识点总结(转)
  14. Servlet第五篇(会话技术之Session)
  15. [spring源码] 小白级别的源码解析ioc(二)
  16. Unity5权威讲解+项目源码+MP4
  17. BAT文件语法和技巧(bat文件的编写及使用)
  18. cogs [HZOI 2015]有标号的二分图计数
  19. 记录一些WPF常用样式方便以后复用(转)
  20. IOCP的缓冲区

热门文章

  1. Eureka参数配置-&gt;Client端参数
  2. jedis 2.9版本部分属性变更
  3. Python简单的登录注册代码
  4. 异步Promise及Async/Await最完整入门攻略
  5. grep、正则表达式
  6. 02&#183;nginx进阶&#183;服务优化配置管理
  7. d3.js 绘制北京市地铁线路状况图(部分)
  8. Spring Boot 2.X(二):集成 MyBatis 数据层开发
  9. Java8 Lambda表达式详解手册及实例
  10. 【原创】(七)Linux内存管理 - zoned page frame allocator - 2