在Unity中實現一個簡單的訊息管理器

敲鍵盤的貓發表於2019-02-16

一直偷懶沒有開發這個東西,最近要做新手引導系統,必須大範圍的解耦,所以不得不用訊息系統來管理了。上網查了幾篇文章,發現一點也不難,但是可能有的教程比較老,或者格式比較亂,所以我重新來寫一個我自己的實現吧,拋磚引玉。

功能介紹

這個管理器,包含幾個部分:

  1. 事件型別的列舉

  2. 事件列表

  3. 監聽器的新增和刪除

  4. 事件傳送

原理簡述

我假定讀者尚不清楚事件管理器的概念。每當一個訊息被觸發的時候,在觸發位置呼叫一下事件傳送的函式。然後這個函式,會去事件列表中定位該事件,找出它對應的回撥函式佇列,逐個執行。如果沒有回撥函式,那麼這個訊息什麼也不做。如果某個類需要監聽某個事件,就將回撥函式註冊進去,如果不需要了,就從佇列中刪除。

關於delegate

這方面網上文章很多,就不詳細介紹了,只說下基本思路。Delegate用來定義一種通用的函式型別,將函式作為引數傳遞,比如
public delegate void Func();
這裡我定義了一個函式形式命名為Func,符合這個結構的,都可以當做這個delegate使用。需要傳入函式作為引數的時候,這樣用:

void Awake(){
    Foo(Test);
}

public void Test(){
    Debug.Log("hello");
}

public void Foo(Func bar){
    bar();
}

具體實現

public enum CustomEventType{
    //事件列表
}

public delegate void EventCallback(object data = null);

public class EventManager{

    private static EventManager _instance;
    public static EventManager instance{
        get{
            if(_instance == null){
                _instance = new EventManager();
            }
            return _instance;
        }
    }

    private static Dictionary<CustomEventType, List<EventCallback>> eventQueue 
    = new Dictionary<CustomEventType, List<EventCallback>>();

    public static void AddListener(CustomEventType type, EventCallback callback){
        if(!eventQueue.ContainsKey(type)){
            eventQueue.Add(type, new List<EventCallback>());
        }
        if(!eventQueue[type].Contains(callback)){
            eventQueue[type].Add(callback);
        }
    }

    public static void RemoveListener(CustomEventType type, EventCallback callback){
        if(eventQueue.ContainsKey(type)){
            eventQueue[type].Remove(callback);
        }
    }

    public static void PostEvent(CustomEventType type){
        if(eventQueue != null && eventQueue.ContainsKey(type)){
            List<EventCallback> callbacks = eventQueue[type];
            for (int i = 0; i < callbacks.Count; i++) {
                callbacks[i]();
            }
        }
    }

}

相關文章