做用:减小代码耦合。
1.消息类型(EventType)
public enum EventType
{
ShowText
}
复制代码
2. 委托,回调函数(CallBack)
public delegate void CallBack();
public delegate void CallBack<T>(T arg);
public delegate void CallBack<T,X>(T arg1,X arg2);
public delegate void CallBack<T,X,Y>(T arg1,X arg2,Y arg3);
public delegate void CallBack<T,X,Y,Z>(T arg1,X arg2,Y arg3,Z arg4);
复制代码
3. 消息处理中心(EventCenter)
using System;
using System.Collections.Generic;
public class EventCenter
{
private static Dictionary<EventType,Delegate> m_EventTable = new Dictionary<EventType, Delegate>();
//注册监听事件
public static void AddListener<T>(EventType eventType, CallBack<T> callBack)
{
if (!m_EventTable.ContainsKey(eventType))
{
m_EventTable.Add(eventType, null);
}
Delegate d = m_EventTable[eventType];
if (d != null && d.GetType() != callBack.GetType())
{
throw new Exception(string.Format("添加监听错误:当前尝试为事件类型{0}添加不一样的委托,本来的委托是{1},现要添加的委托是{2}", eventType,
d.GetType(),
callBack.GetType()));
}
m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] + callBack;
}
//移除监听事件
public static void RemoveListener<T>(EventType eventType, CallBack<T> callBack)
{
if (m_EventTable.ContainsKey(eventType))
{
Delegate d = m_EventTable[eventType];
if (d == null)
{
throw new Exception(string.Format("移除监听错误:事件{0}不存在委托", eventType));
}
else if (d.GetType() != callBack.GetType())
{
throw new Exception(string.Format("移除监听错误:尝试为事件{0}移除不一样的委托,原先的委托为{1},如今要移除的委托为{2}", eventType, d.GetType(), callBack.GetType()));
}
}
else
{
throw new Exception(string.Format("移除监听错误:不存在事件{0}", eventType));
}
m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] - callBack;
if (m_EventTable[eventType] == null)
{
m_EventTable.Remove(eventType);
}
}
//广播事件
public static void Broadcast<T>(EventType eventType,T arg)
{
Delegate d;
if (m_EventTable.TryGetValue(eventType, out d))
{
CallBack<T> callBack = d as CallBack<T>;
if (callBack != null)
{
callBack(arg);
}
else
{
throw new Exception(string.Format("事件广播错误:事件{0}存在不一样的委托类型", eventType));
}
}
}
}
复制代码
使用这个系统,实现一个按钮按下,显示文本信息
- 在一个Text对象上挂载一个ShowText.cs的脚本,脚本以下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ShowText : MonoBehaviour
{
void Awake()
{
EventCenter.AddListener<string>(EventType.ShowText,Show);
}
void OnDestory()
{
EventCenter.RemoveListener<string>(EventType.ShowText,Show);
}
public void Show(string str)
{
this.gameObject.GetComponent<Text>().text = str;
}
}
复制代码
- 在一个Button对象上挂载一个BtnClick.cs脚本,脚本以下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BtnClick : MonoBehaviour
{
// Use this for initialization
void Start ()
{
this.GetComponent<Button>().onClick.AddListener(() => { EventCenter.Broadcast(EventType.ShowText,"被点击了"); });
}
}复制代码
仓库代码:https://gitee.com/hankangwen/EventBroadcastSystem