# 1.前言
Unity中事件/委託有着普遍的應用,本文經過封裝一個簡易的事件的系統,來統一管理消息的傳遞。此功能在簡易應用或者事件較少的體現不出太好的做用,可是對於事件應用較多時,能夠減小腳本之間的耦合。經過此事件系統架起不一樣腳本之間的橋樑,對於大量應用事件場景 中具備良好的效果。android
# 2.事件系統
## 2.1 事件管理類
管理事件的註冊與廣播編程
```csharp
using System;
using System.Collections.Generic;優化
namespace EventManager
{
public delegate void ActionHandler(Message message);this
public class EventManager
{
#region Instance
private static EventManager instance;spa
public static EventManager GetInstance()
{
if (instance == null)
{
instance = new EventManager();
}orm
return instance;
}繼承
private EventManager() { }
#endregion事件
private Dictionary<string, ActionHandler> actions = new Dictionary<string, ActionHandler>();string
public void AddListener(string actionKey,ActionHandler action)
{
ActionHandler handler;
bool exist = actions.TryGetValue(actionKey, out handler);it
if (exist)
{
//避免重複添加
Delegate[] delegates = handler.GetInvocationList();
if (Array.IndexOf(delegates, action) == -1)
{
handler += action;
actions[actionKey] = handler;
}
}
else
{
actions.Add(actionKey, action);
}
}
public void RemoveListener(string actionKey,ActionHandler action)
{
ActionHandler handler;
bool exist = actions.TryGetValue(actionKey, out handler);
if (exist)
{
handler -= action;
if (handler == null)
{
actions.Remove(actionKey);
}
else
{
actions[actionKey] = handler;
}
}
}
public bool BroadcastMessage(string actionKey, Message message)
{
ActionHandler handler;
bool exist = actions.TryGetValue(actionKey, out handler);
if (exist)
{
handler(message);
return true;
}
else
{
return false;
}
}
}
}
```
## 2.2 消息類
經過統一的消息類來傳遞參數,避免泛型編程時須要考慮的多種狀況。以下所示Message類,此類的參數參考android的handler類參數。能夠經過繼承Message的新類來傳遞自定義參數。
```csharp
namespace EventManager
{
public class Message
{
public int arg1;
public int arg2;
public string message;
public Message(int arg1, int arg2, string message)
{
this.arg1 = arg1;
this.arg2 = arg2;
this.message = message;
}
public Message() { }
}
}
```
## 2.3 事件標記
在EventManager中 註冊事件時,經過string類型的參數來標記須要廣播事件。此處能夠改成枚舉類型,後續能夠優化。
```csharp
namespace EventManager
{
public class EventType
{
public readonly static string EVENTTYPE_METHOD1 = "EventType_Method1";
}
}
```
# 3.應用案例
```csharp
using MSG;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EventManagerTest : MonoBehaviour
{
public Button button;
private void Start()
{
button.onClick.AddListener(() =>
{
EventManager.EventManager.GetInstance().BroadcastMessage(EventManager.EventType.EVENTTYPE_METHOD1, new EventManager.Message());
});
}
void OnEnable ()
{
EventManager.EventManager.GetInstance().AddListener(EventManager.EventType.EVENTTYPE_METHOD1, Method);
}
private void OnDisable()
{
EventManager.EventManager.GetInstance().RemoveListener(EventManager.EventType.EVENTTYPE_METHOD1, Method);
}
void Method(EventManager.Message message)
{
Debug.Log("Method : Message -{0}- obtained from channel {1}");
}
void Method1(Message message)
{
Debug.LogFormat("Method1 : Message -{0}- obtained from channel {1}", message.arg1, message.what);
}
void Method2(Message message)
{
NetworkMessage networkMessage = message as NetworkMessage;
if(networkMessage != null)
{
Debug.LogFormat("NetworkMessage obtained from channel {0}", message.what);
}
}
}
```