unity message
再用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的更多相关文章
- Eclipse 4.2 failed to start after TEE is installed
--------------- VM Arguments--------------- jvm_args: -Dosgi.requiredJavaVersion=1.6 -Dhelp.lucene ...
- Unity API学习笔记(2)-GameObject的3种Message消息方法
官方文档>GameObject 首先建立测试对象: 在Father中添加两个脚本(GameObejctTest和Target),分别用来发送Message和接受Message: 在其它GameO ...
- Unity游戏内版本更新
最近研究了一下游戏内apk包更新的方法. ios对于应用的管理比较严格,除非热更新脚本,不太可能做到端内大版本包的更新.然而安卓端则没有此限制.因此可以做到不跳到网页或应用商店,就覆盖更新apk包. ...
- Unity 处理IOC AOP
用Unity 可以做IOC(控制反转) AOP(切面)可以做统一的异常和日志处理,非常方便,项目中是用微软企业库中的Microsoft.Practices.Unity实现 1 定义接口与实现 //定义 ...
- Unity 最佳实践
转帖:http://www.glenstevens.ca/unity3d-best-practices/ 另外可以参考:http://devmag.org.za/2012/07/12/50-tips- ...
- 开源Unity小插件CheatConsole
我们在开发游戏的过程中,通常都需要一些快捷的方式来进行一些非常规的测试,这些功能一般被称作控制台或者GM指令,比如虚幻竞技场中,可以使用~键呼出控制台,输入一些指令即可进行快捷设置,比如设置分辨率,全 ...
- Unity.Interception(AOP)
在前面我们学习到的是Unity依赖注入(DI)与统一容器来松散耦合,这个设计已经对我们系统带来了很多的好处.但是我们还会想尝试和遵循单一职责,开放封闭原则.比如我们不应该在我们的Bus ...
- 基于Unity有限状态机框架
这个框架是Unity wiki上的框架.网址:http://wiki.unity3d.com/index.php/Finite_State_Machine 这就相当于是“模板”吧,自己写的代码,写啥都 ...
- Unity、Exception Handling引入MVP
什么是MVP?在“MVP初探”里就有讲过了,就是一种UI的架构模式. 简单的描述一下Unity和Exception Handling Application Block: Unity是一个轻量级的可扩 ...
随机推荐
- HNU_小初高数学学习软件_功能说明
结对编程项目主要功能: 1.用户注册功能.用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册: 2.用户完成注册后,界面提示设置密码,用户输入两次密码匹配后设置密码成功.密码6-1 ...
- 关于react-router最新版本的使用
现在react-router已经更新到了5.1.1版本,在一些使用方法上较之前有了很多改变,现做初步列举,以后会陆续更新. 关于引入react-router和基本使用 旧版本中引入react-rout ...
- 【求赐教】VMware workstation 转VSphere
首先我从其他电脑拷贝过来一台虚拟机(这个说法不知道准不准确,就是把所有文件夹都拷贝过来了),然后打开VMware,通过"打开虚拟机"这个操作,直接找到本地的.vmx文件,如下图所示 ...
- Terminal MultipleXer---终端复用器tmux基本使用
Terminal MultipleXer---终端复用器tmux 使用场景:1.scp大文件 2:编译大文件 3:多窗口对比文件 1.安装tmux [root@localhost ~]# yum in ...
- 43 道检验基础的 JavaScript 面试题
导读 这两天的GitHub Trending repositories被一个名叫 javascript-questions的项目霸榜了,项目中记录了一些JavaScript题目. 文中有些点作者解释的 ...
- Mysql高手系列 - 第19篇:mysql游标详解,此技能可用于救火
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第19篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符 ...
- ELK 学习笔记之 elasticsearch head插件安装
elasticsearch head插件安装: 准备工作: 安装nodejs和npm https://nodejs.org/en/download/ node-v6.11.2-linux-x64.ta ...
- 利用C++实现模块隐藏(R3层断链)
一.模块隐藏的实现原理 普通API查找模块实现思路:其通过查询在R3中的PEB(Process Environment Block 进程环境块)与TEB(Thread Environment Bloc ...
- SpringBootSecurity学习(23)前后端分离版之OAuth2.0 其它模式
密码模式 前面介绍了授权码模式和刷新令牌两种获取最新令牌的方法,下面来看一下其它模式.首先看密码模式,我们默认配置的三种模式中其实就包含密码模式的支持: 因此我们启动项目,直接使用密码模式即可,访问地 ...
- postman环境变量设置
1.点击小齿轮进入到环境变量添加页面,点击add添加环境变量 2.输入变量名称和变量值 3.添加成功 4.接口中设置变量