版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/CJB_King/article/details/78973727
消息事件的监听与分发
Unity游戏中通常使用的消息事件是直接使用委托实现的,这个对开发团队来说是件麻烦的事,所以需要封装
一个统一的接口供开发者使用,使用事件机制的优点是不需要在UI上直接挂接代码。
首先定义一个消息事件的基类,这个是消息底层的实现方式,主要目的是初始化消息;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum CEventType //事件类型,最好放在单独的脚本中
{
GAME_OVER,
GAME_WIN,
PAUSE,
ENERGY_EMEPTY,
GAME_DATA,
}
public class CBaseEvent {
protected Hashtable arguments; //哈希表用来存储委托事件
protected CEventType type; //事件类型
protected Object sender; //存储事件分发的对象
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 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;
this.sender = sender;
if(this.arguments==null)
{
arguments = new Hashtable();
}
}
public CBaseEvent(CEventType type,Hashtable args,Object sender)
{
this.type = type;
this.arguments = args;
this.sender = sender;
if(this.arguments==null)
{
this.arguments = new Hashtable();
}
}
}
事件的监听和分发接口封装在游戏逻辑中经常呗调用,同时也是对外提供的接口:
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 cEventDelegate = this.listeners[eventType] as CEventListenerDelegate;
cEventDelegate = (CEventListenerDelegate)Delegate.Combine(cEventDelegate, listener);
//上面相当于 //cEventDelegate += listener;
this.listeners[eventType] = cEventDelegate;
}
public void RemoveEventListener(CEventType eventType,CEventListenerDelegate listener)
{
CEventListenerDelegate cEventDelegate = this.listeners[eventType] as CEventListenerDelegate;
if(cEventDelegate!=null)
{
cEventDelegate = (CEventListenerDelegate)Delegate.Remove(cEventDelegate,listener);
//上面相当于 //cEventDelegate -= listener;
}
this.listeners[eventType] = cEventDelegate;
}
public void DispatchEvent(CBaseEvent evt) //触发函数
{
CEventListenerDelegate cEventDelegate = this.listeners[evt.Type] as CEventListenerDelegate;
if(cEventDelegate!=null)
{
try
{
cEventDelegate(evt); //内置触发函数
}
catch(System.Exception e)
{
throw new System.Exception(string.Concat(new string[]
{
"Error dispathcing event",
evt.Type.ToString(),
":",
e.Message,
" ",
e.StackTrace
}),e);
}
}
}
public void RemoveAll()
{
this.listeners.Clear();
}
}
下面是监听和分发的使用
CEventDispatcher.GetInstance().AddEventListener(CEventType.GAME_WIN, NumberListener);//添加监听事件
CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.GAME_WIN, this)); //触发NumberListener函数
完整调用实例
public class CEventDelegateExample : MonoBehaviour {
void Start () {
CEventDispatcher.GetInstance().AddEventListener(CEventType.GAME_WIN, NumberListener);//添加监听事件
}
void Update () {
if(Input.GetMouseButtonDown(0))
{
CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.GAME_WIN, this)); //如果按下鼠標左键,触发NumberListener函数
}
}
void OnDestroy()
{
CEventDispatcher.GetInstance().RemoveEventListener(CEventType.GAME_WIN, NumberListener);
}
public void NumberListener(CBaseEvent evt)
{
Debug.Log("Mouse Down");
}
}