1. 程式人生 > >Unity實現自己的事件機制(簡單實現)

Unity實現自己的事件機制(簡單實現)

事件機制廣泛應用於mvc模式中,靈活的事件機制能夠彌補Unity中的一些缺陷,比如協程的執行。因為協程不能返回值,也不能通過out或者ref傳遞。通過事件機制,可以知道協程執行進度並且返回執行結果。當然,這只是個舉例,也只是我習慣用的一種方式。如果有更好的實現方式,希望不吝賜教。

所有要接受事件的指令碼,都要繼承這個事件手柄的介面

/// <summary>
/// 事件手柄
/// </summary>
public interface IEventHandler {

    void OnEvent(string type,object data);
}

以下是EventManager的主要內容,實現了註冊監聽,移除監聽,派發事件等基本方法。只要在事件派發前,註冊好就可以運行了!

using UnityEngine;
using System.Collections.Generic;

public class EventManager {

    private static EventManager instance;

    private Dictionary<string, List<IEventHandler>> dicHandler;

    private EventManager()
    {
        dicHandler = new Dictionary<string, List<IEventHandler>>();
    }

    public static EventManager GetInstance()
    {
        if (instance == null)
        {
            instance = new EventManager();
        }
        return instance;
    }

    /// <summary>
    /// 註冊事件監聽
    /// </summary>
    /// <param name="type">監聽型別</param>
    /// <param name="listher">監聽物件</param>
    public void AddEventListener(string type, IEventHandler listher)
    {
        if (!dicHandler.ContainsKey(type))
        {
            dicHandler.Add(type,new List<IEventHandler>());
        }
        dicHandler[type].Add(listher);
    }

    /// <summary>
    /// 移除對type的所有監聽
    /// </summary>
    /// <param name="type"></param>
    public void RemoveEventListener(string type)
    {
        if (dicHandler.ContainsKey(type))
        {
            dicHandler.Remove(type);
        }
    }

    /// <summary>
    /// 移除監聽者的所有監聽
    /// </summary>
    /// <param name="listener">監聽者</param>
    public void RemoveEventListener(IEventHandler listener)
    {
        foreach (var item in dicHandler)
        {
            if (item.Value.Contains(listener))
            {
                item.Value.Remove(listener);
            }
        }
    }

    /// <summary>
    /// 清空所有監聽事件
    /// </summary>
    public void ClearEventListener()
    {
        Debug.Log("清空對所有所有所有事件的監聽");
        if (dicHandler!=null)
        {
            dicHandler.Clear();
        }
    }

    /// <summary>
    /// 派發事件
    /// </summary>
    /// <param name="type">事件型別</param>
    /// <param name="data">事件傳達的資料</param>
    public void DispachEvent(string type, object data)
    {
        if (!dicHandler.ContainsKey(type))
        {
            Debug.Log("Did not add any IEventHandler of " + type + " in EventManager!");
            return;
        }

        List<IEventHandler> list = dicHandler[type];
        for (int i = 0; i < list.Count; i++)
        {
            list[i].OnEvent(type,data);
        }
    }
}