做用:減小代碼耦合。
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