再用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);

unity message的更多相关文章

  1. Eclipse 4.2 failed to start after TEE is installed

    ---------------  VM Arguments---------------  jvm_args: -Dosgi.requiredJavaVersion=1.6 -Dhelp.lucene ...

  2. Unity API学习笔记(2)-GameObject的3种Message消息方法

    官方文档>GameObject 首先建立测试对象: 在Father中添加两个脚本(GameObejctTest和Target),分别用来发送Message和接受Message: 在其它GameO ...

  3. Unity游戏内版本更新

    最近研究了一下游戏内apk包更新的方法. ios对于应用的管理比较严格,除非热更新脚本,不太可能做到端内大版本包的更新.然而安卓端则没有此限制.因此可以做到不跳到网页或应用商店,就覆盖更新apk包. ...

  4. Unity 处理IOC AOP

    用Unity 可以做IOC(控制反转) AOP(切面)可以做统一的异常和日志处理,非常方便,项目中是用微软企业库中的Microsoft.Practices.Unity实现 1 定义接口与实现 //定义 ...

  5. Unity 最佳实践

    转帖:http://www.glenstevens.ca/unity3d-best-practices/ 另外可以参考:http://devmag.org.za/2012/07/12/50-tips- ...

  6. 开源Unity小插件CheatConsole

    我们在开发游戏的过程中,通常都需要一些快捷的方式来进行一些非常规的测试,这些功能一般被称作控制台或者GM指令,比如虚幻竞技场中,可以使用~键呼出控制台,输入一些指令即可进行快捷设置,比如设置分辨率,全 ...

  7. Unity.Interception(AOP)

            在前面我们学习到的是Unity依赖注入(DI)与统一容器来松散耦合,这个设计已经对我们系统带来了很多的好处.但是我们还会想尝试和遵循单一职责,开放封闭原则.比如我们不应该在我们的Bus ...

  8. 基于Unity有限状态机框架

    这个框架是Unity wiki上的框架.网址:http://wiki.unity3d.com/index.php/Finite_State_Machine 这就相当于是“模板”吧,自己写的代码,写啥都 ...

  9. Unity、Exception Handling引入MVP

    什么是MVP?在“MVP初探”里就有讲过了,就是一种UI的架构模式. 简单的描述一下Unity和Exception Handling Application Block: Unity是一个轻量级的可扩 ...

随机推荐

  1. mysql 最左前缀匹配原则

    1.在mysql建立联合索引时会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配,示例:对列col1.列col2和列col3建一个联合索引 KEY index_col1_co ...

  2. ArchLinux安(重)装指南

    说实话,我其实是不想要出这篇博客的.在我这一个月安装Arch的过程中,让我感触比较深的一点是: 没有谁比这个系统的官方更懂它. 尤其是这种比较复杂的系统,更是如此. 这几天,我经历了一次重装,系统坏了 ...

  3. JSON说明

    1. JSON 数据的书写格式 对象:是一个无序的“‘名称/值’对”集合.一个对象以“{”(左括号)开始,“}”(右括号)结束.每个“名称”后跟一个“:”(冒号):“‘名称/值’ 对”之间使用“,”( ...

  4. jq方法写选项卡的基本原理以及三种方法

    使用jq写选项卡,告别了繁琐的循环以及命名规范 基本原理: 1.当某一个btn被选中时,将这个btn的背景颜色设为橘色,其余兄弟btn背景颜色设为空(none) 2.如果子div与btn的索引相同,就 ...

  5. Spring Boot 2.X(四):Spring Boot 自定义 Web MVC 配置

    0.准备 Spring Boot 不仅提供了相当简单使用的自动配置功能,而且开放了非常自由灵活的配置类.Spring MVC 为我们提供了 WebMvcConfigurationSupport 类和一 ...

  6. 【Java】支付宝获取人脸采集认证的图片base64格式

    人脸识别结果查询接口zoloz.identification.user.web.query返回的imgStr图片字符串并不是标准的base64格式,解析不出图片. 由于标准的Base64并不适合直接放 ...

  7. 【MySQL】 用户授权

    启动mysql命令符 grant all privileges on mysql.* to 'root'@'%' identified by '123456'; 给mysql用户root授权,'%'表 ...

  8. redis mysql 连接池 之 golang 实现

    1 mysql 连接池代码 package lib import ( "database/sql" "fmt" "strconv" &quo ...

  9. SDN网络IPv6组播机制支持实时视频业务海量用户扩展

    以 OpenFlow 技术为核心的软件定义网络(SDN)框架具有集中控制的功能能够自己感知网络拓扑的变化,在细粒度的路径选择.接入控制.负载均衡方面有着天然的优势,为 IPv6 组播功能的实现提供了好 ...

  10. Have a Good Attitude 良好的态度

    Poor attitudes lead to poor communication. Poor communication leads to poor service. Poor service le ...