再用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. SPSS学习笔记参数检验—单样本t检验

    单样本t检验 目的:利用来自总体的样本数据,推断该总体的均值是否与指定的检验值存在差异. 适用条件:样本来自的总体应服从或者近似服从正态分布. 注:当样本量n比较大时:由中心极限定理得知,即使原数据不 ...

  2. Springboot2.1.x配置Activiti7单独数据源问题

    Springboot2.1.x配置Activiti7单独数据源问题 简介 最近基于最新的Activiti7配置了SpringBoot2. 简单上手使用了一番.发现市面上解决Activiti7的教程很少 ...

  3. Asteroids POJ - 3041 二分图最小点覆盖

       Asteroids POJ - 3041 Bessie wants to navigate her spaceship through a dangerous asteroid field in ...

  4. .Net Core 商城微服务项目系列(十三):搭建Log4net+ELK+Kafka日志框架

    之前是使用NLog直接将日志发送到了ELK,本篇将会使用Docker搭建ELK和kafka,同时替换NLog为Log4net. 一.搭建kafka 1.拉取镜像 //下载zookeeper docke ...

  5. Winows 2008远程桌面访问多用户设置

    一张图

  6. 完美实现保存和加载easyui datagrid自定义调整列宽位置隐藏属性功能

    需求&场景 例表查询是业务系统中使用最多也是最基础功能,但也是调整最平凡,不同的用户对数据的要求也不一样,所以在系统正式使用后,做为开发恨不得坐在业务边上,根据他们的要求进行调整,需要调整最多 ...

  7. LAMP环境部署物联网项目

    今天来在LAMP环境下搭建一个PHP项目,开始之前,先来普及下物联网常识: 物联网,即Internet of Things,简写IOT.让所有能行使独立功能的普通物体实现互联互通的网络,通过物联网可以 ...

  8. Kubernetes网络分析之Flannel

    Flannel是cereos开源的CNI网络插件,下图flannel官网提供的一个数据包经过封包.传输以及拆包的示意图,从这个图片中可以看出两台机器的docker0分别处于不同的段:10.1.20.1 ...

  9. Java总结---继承(不断完善ing..)

    java三大特性:封装.继承.多态 继承 一.目的:实现代码的复用 二.简单例子(A继承了C): public class A extends C { //检测哪些可以在子类里使用 public vo ...

  10. 使用Swagger服务搭建.Net Core API

    使用Swagger服务搭建.Net Core API 创建.Net Core API 新建项目.文件——新建——项目 选择应用程序模板. 设置存放路径,命名方案名称. 创建API. 搭建成功. 使用S ...