unity消息系统机制,工具类可以直接使用
2017-10-31 14:14
239 查看
转自:http://www.manew.com/blog-117699-43032.html
在开发Unity的时候,为了方便开发一般都会采用消息事件,消息事件主要是做啥的?我们如何去封装,如何去运用消息事件处理事情。接下来就给大家介绍一下:
消息事件顾名思义,是通过消息触发的事件。比如大家去完成某个任务,完成后才会触发另一个事件的发生,这种情况我们就会使用消息事件等等吧。
消息事件的使用主要是通过添加消息监听,然后分发消息处理事情。
那我们如何去封装我们的消息系统,在这里我把代码给大家分享一下:
1.首先我们封装消息事件的基类CBaseEvent.cs
2.以上是消息基类的定义。那接下来就是封装对外使用的消息接口了。写一个新的类CEventDispatcher
3.一共就这2个类就可以了,接下来是使用方法
在开发Unity的时候,为了方便开发一般都会采用消息事件,消息事件主要是做啥的?我们如何去封装,如何去运用消息事件处理事情。接下来就给大家介绍一下:
消息事件顾名思义,是通过消息触发的事件。比如大家去完成某个任务,完成后才会触发另一个事件的发生,这种情况我们就会使用消息事件等等吧。
消息事件的使用主要是通过添加消息监听,然后分发消息处理事情。
那我们如何去封装我们的消息系统,在这里我把代码给大家分享一下:
1.首先我们封装消息事件的基类CBaseEvent.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public enum CEventType { GAME_OVER, GAME_WIN, PAUSE, GAME_DATA, } public class CBaseEvent { protected Hashtable arguments; protected CEventType type; protected object sender; protected string eventName; public CEventType Type { get { return this.type; } set { this.type = value; } } public IDictionary Params { get { return this.arguments; } set { this.arguments = (value as Hashtable); } } public object Sender { get { return this.sender; } set { this.sender = value; } } public string EventName { get { return eventName; } set { eventName = value; } } public override string ToString() { return this.type + " { " + ((this.sender == null) ? "null" : this.sender.ToString()) + " } "; } public CBaseEvent Clone() { return new CBaseEvent(this.type, this.arguments, Sender); } public CBaseEvent(CEventType type, object sender) { this.Type = type; Sender = sender; if (this.arguments == null) { this.arguments = new Hashtable(); } } public CBaseEvent(CEventType type, Hashtable args, object sender) { this.Type = type; this.arguments = args; Sender = sender; if (this.arguments == null) { this.arguments = new Hashtable(); } } public CBaseEvent(string eventName, object sender) { this.EventName = eventName; Sender = sender; if (this.arguments == null) { this.arguments = new Hashtable(); } } }
2.以上是消息基类的定义。那接下来就是封装对外使用的消息接口了。写一个新的类CEventDispatcher
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public delegate void CEventListenerDelegate(CBaseEvent evt); public class CEventDispatcher { static CEventDispatcher instance; public static CEventDispatcher GetInstance() { if (instance == null) { instance = new CEventDispatcher(); } return instance; } private Hashtable listeners = new Hashtable(); public void AddEventListener(CEventType eventType, CEventListenerDelegate listener) { CEventListenerDelegate ceventListenerDelegate = this.listeners[eventType] as CEventListenerDelegate; ceventListenerDelegate = (CEventListenerDelegate)Delegate.Combine(ceventListenerDelegate, listener); this.listeners[eventType] = ceventListenerDelegate; } public void RemoveEventListener(CEventType eventType, CEventListenerDelegate listener) { CEventListenerDelegate ceventListenerDelegate = this.listeners[eventType] as CEventListenerDelegate; if (ceventListenerDelegate != null) { ceventListenerDelegate = (CEventListenerDelegate)Delegate.Remove(ceventListenerDelegate, listener); } this.listeners[eventType] = ceventListenerDelegate; } public void AddEventListener(string eventName, CEventListenerDelegate listener) { CEventListenerDelegate ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegate; //这个combine就相当于委托的+= (整体的实现就是类似于观察者模式) ceventListenerDelegate = (CEventListenerDelegate)Delegate.Combine(ceventListenerDelegate, listener); this.listeners[eventName] = ceventListenerDelegate; } public void RemoveEventListener(string eventName, CEventListenerDelegate listener) { CEventListenerDelegate ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegate; if (ceventListenerDelegate != null) { ceventListenerDelegate = (CEventListenerDelegate)Delegate.Remove(ceventListenerDelegate, listener); } this.listeners[eventName] = ceventListenerDelegate; } public void DispatchEventOnce(CBaseEvent evt) { CEventListenerDelegate ceventListenerDelegate; if (string.IsNullOrEmpty(evt.EventName)) { ceventListenerDelegate = this.listeners[evt.Type] as CEventListenerDelegate; } else { ceventListenerDelegate = this.listeners[evt.EventName] as CEventListenerDelegate; } if (ceventListenerDelegate != null) { try { ceventListenerDelegate(evt); if (string.IsNullOrEmpty(evt.EventName)) { this.listeners.Remove(evt.Type); } else { this.listeners.Remove(evt.EventName); } } catch (Exception ex) { throw new Exception(string.Concat(new string[] { "Error dispatching event ", evt.Type.ToString(), ": ", ex.Message, " ", ex.StackTrace }), ex); } } } /// /// 使用枚举传递 /// /// public void DispatchEvent(CBaseEvent evt) { CEventListenerDelegate ceventListenerDelegate = this.listeners[evt.Type] as CEventListenerDelegate; if (ceventListenerDelegate != null) { try { ceventListenerDelegate(evt); } catch (Exception ex) { throw new Exception(string.Concat(new string[] { "Error dispatching event ", evt.Type.ToString(), ": ", ex.Message, " ", ex.StackTrace }), ex); } } } /// /// 使用字符串传递 /// /// public void DispatchStringEvent(CBaseEvent evt) { CEventListenerDelegate ceventListenerDelegate = this.listeners[evt.EventName] as CEventListenerDelegate; if (ceventListenerDelegate != null) { try { ceventListenerDelegate(evt); } catch (Exception ex) { throw new Exception(string.Concat(new string[] { "Error dispatching event ", evt.Type.ToString(), ": ", ex.Message, " ", ex.StackTrace }), ex); } } } public void RemoveAll() { this.listeners.Clear(); } }
3.一共就这2个类就可以了,接下来是使用方法
using UnityEngine; using System.Collections; public class TestEvent : MonoBehaviour { // Use this for initialization void Start () { CEventDispatcher.GetInstance().AddEventListener("开始触发", MyTestFunc); CEventDispatcher.GetInstance().AddEventListener(CEventType.GAME_WIN, MyTestFunc); CEventDispatcher.GetInstance().DispatchEventOnce(new CBaseEvent("开始触发","第一次")); CEventDispatcher.GetInstance().DispatchStringEvent(new CBaseEvent("开始触发", "第三次")); CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.GAME_WIN, "事件类型")); } void MyTestFunc(CBaseEvent evt) { Debug.Log("触发了该方法:"+ evt.Sender.ToString()); } }
相关文章推荐
- Dom4j处理大数据的工具类(直接可以使用)
- SQL2000系统表、存储过程、函数的功能介绍及应用2009年01月21日 星期三 11:38虽然使用系统存储过程、系统函数与信息架构视图已经可以为我们提供了相当丰富的元数据信息,但是对于某些特殊的元数据信息,我们仍然需要直接对系统表进行查询。因为SQL
- 【小松教你手游开发】【unity实用技能】拓展函数(给系统代码添加可直接使用的接口)
- 利用运行时,给UIImageView写一个分类,交换里面的setImage的方法,可以重绘图片,提高内存的利用率(要是没有重绘图片,直接使用系统提供的setImag就会造成占用大量的内存问题)
- Unity 怎么得到一个可以直接使用的对象与另一个对象之间的Float夹角
- 虚拟字符驱动,申请n页内存,使用mmap映射到应用程序空间,用户就可以直接访问不需要任何同步机制
- Unity 3D 消息事件系统 NotificationCenter、CEventDispatcher事件分发机制
- 之前生成的.ssh可以直接放入Mac系统user/your_name中使用
- 【小松教你手游开发】【unity实用技能】拓展函数(给系统代码添加可直接使用的接口)
- 使用xmlhttp和Java session监听改善站内消息系统
- SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ol
- 使用SendMessage方法对窗体上的控件进行截图,该方法的思想就是把控件的句柄拿到,对控件发送WM_PAINT消息,并且把希望得到图形对象的句柄当作wParam参数传过去,这样就可以在图形对象得到想要得图形。
- 绕过 libc 直接使用系统调用
- 使用xmlhttp和Java session监听改善站内消息系统
- SQLite for uClinux(一个可以在嵌入式系统中使用的小型数据库)
- 使用xmlhttp和Java session监听改善站内消息系统
- 深度解析ASP.NET2.0中的Callback机制callback的一般使用方法还算简单,直接参照
- 使用Visual Studio.Net,系统报告“automation服务器不能创建对象”错误。解决之道运行:regsvr32 scrrun.dll 就可以了。
- 使用VIM可以直接把语法加亮的Source Code转换为HTML格式的页面!