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类的开头定义了枚举,把你的消息字符串,换成枚举就行了,因为我已经写好了重载方法,可以直接使用
本文介绍了一个Unity中自定义的消息传递机制实现,包括消息基类、消息接口封装、发送消息及接收消息的具体步骤。该机制支持枚举和字符串类型的消息,并通过实例展示了如何在游戏开发中进行消息的发送与接收。

被折叠的 条评论
为什么被折叠?



