1.消息基类 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.封装对外使用的消息接口 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; } /// <summary> /// 使用枚举传递 /// </summary> /// <param name="evt"></param> 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); } } } /// <summary> /// 使用字符串传递 /// </summary> /// <param name="evt"></param> 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.开始使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 发送消息的一方
/// </summary>
public class PostBtn : MonoBehaviour
{
public void OnBtn()
{
//第一个参数是事件的名称,第二个参数是传递的数值
//CEventDispatcher.GetInstance().DispatchStringEvent(new CBaseEvent("开始触发", "这是重要数值"));
CEventDispatcher.GetInstance().DispatchStringEvent(new CBaseEvent("TestMethod", Camera.main));
}
}
4.接收方这边首先要在Start()的方法里面刚开始就要去监听这个消息
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReceiveObject : MonoBehaviour {
public void Start()
{
//消息机制,监听
//第一个参数是事件名称,注意要与发送方的事件名称要一致,第二个是触发的方法MyTestFunc,
//可以自定义,方法名随便写,注意必须有个CBaseEvent类型的参数
CEventDispatcher.GetInstance().AddEventListener("TestMethod", CreateGoLobby);
}
public void CreateGoLobby(CBaseEvent evt)
{
print("我是参数" + evt);
}
}
只要把上面的2个类拷贝到你的工程里面就可以用了
同时,除了支持 字符串类型的消息,还支持枚举类型的消息
已经在CBaseEvent.cs类的开头定义了枚举,把你的消息字符串,换成枚举就行了,因为我已经写好了重载方法,可以直接使用