簡易的EventManager實現

首先,這篇博文是參考了http://blog.sina.com.cn/s/blog_5b6cb9500102uypp.html 這個文章作者的思路而設計的。經過自己的理解後,模仿了一個消息系統給自己用,下面談談對這個系統的認識和看法。

我所製作的EventManager的核心是:
1.把我們遊戲中所有用到的方法,全部放在一個枚舉中,如下:

public enum GameEvent
{
    //這裏是定義玩家的事件
    PLAYER_ATTACK,
    PLAYER_DEATH,
    PLAYER_SPEAK,
    PLAYER_GAINLIFE,
    PLAYER_REDUCELIFE,


    //這裏是定義怪物的事件
    ENEMY_DEATH,
    ENEMY_ATTACK,
    ENEMY_REDUCELIFE,
}

2.建立一個字典容器,然後在遊戲初始化的時候把遊戲中所有的事件即上面的GameEvent全部保存在字典的key中,這樣我們就把遊戲內所有的事件名全部放在了一個字典中。代碼如下:

//建立委託
    public delegate void CommonEvent(object data);

    //建立事件列表
    public Dictionary<GameEvent, CommonEvent> eventDic = new Dictionary<GameEvent, CommonEvent>();

    /// <summary>
    /// 事件初始化
    /// </summary>
    public void InitEvent()
    {

        foreach (GameEvent key in Enum.GetValues(typeof(GameEvent)))
        {
            AddEvent(key);
        }
    }
        /// <summary>
    /// 添加一個回調事件
    /// </summary>
    /// <param name="key"></param>
    void AddEvent(GameEvent key)
    {
        eventDic.Add(key, delegate (object data) { });
    }

3.我們給這個類添加3個行爲,分別是註冊事件,執行事件,解綁事件。它們的作用就是我們在遊戲中將所有需要實體和對象,當他們需要和其他對象進行交互的時候,我們首先將所有對象的每一個交互行爲添加在GameEvent枚舉中,然後在這些對象進行初始化的時候,把這個對象的行爲利用EventManager的註冊方法註冊進入字典中;在對象需要相互交互的時候,我們直接調用EventManager的執行事件調用相應的方法;在對話被銷燬的時候我們執行EventManager的解綁事件方法,如下:

    /// <summary>
    /// 觸發事件
    /// </summary>
    /// <param name="key"></param>
    /// <param name="param"></param>
    public void TriggerEvent(GameEvent key,object param)
    {
        if (eventDic.ContainsKey(key))
        {
            eventDic[key](param);
        }
        else
        {
            Debug.LogError("沒有定義的事件:" + key);
        }
    }

    /// <summary>
    /// 綁定一個事件
    /// </summary>
    /// <param name="key">事件的key</param>
    /// <param name="attachEvent">事件的方法</param>
    public void AttachEvent(GameEvent key , CommonEvent attachEvent)
    {
        if (eventDic.ContainsKey(key))
        {
            eventDic[key] += attachEvent;
        }
        else
        {
            Debug.LogError("沒有定義的事件:" + key);
        }
    }

    /// <summary>
    /// 解綁一個事件
    /// </summary>
    /// <param name="key">事件的key</param>
    /// <param name="detachEvent">要解除的事件方法</param>
    public void DetachEvent(GameEvent key , CommonEvent detachEvent)
    {
        if (eventDic.ContainsKey(key))
        {
            eventDic[key] -= detachEvent;
        }
        else
        {
            Debug.LogError("沒有定義的事件:" + key);
        }
    }

以下是完整代碼:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public enum GameEvent
{
    //這裏是定義玩家的事件
    PLAYER_ATTACK,
    PLAYER_DEATH,
    PLAYER_SPEAK,
    PLAYER_GAINLIFE,
    PLAYER_REDUCELIFE,


    //這裏是定義怪物的事件
    ENEMY_DEATH,
    ENEMY_ATTACK,
    ENEMY_REDUCELIFE,
}
public class EventManager{

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

    //建立委託
    public delegate void CommonEvent(object data);

    //建立事件列表
    public Dictionary<GameEvent, CommonEvent> eventDic = new Dictionary<GameEvent, CommonEvent>();

    /// <summary>
    /// 事件初始化
    /// </summary>
    public void InitEvent()
    {

        foreach (GameEvent key in Enum.GetValues(typeof(GameEvent)))
        {
            AddEvent(key);
        }
    }

    /// <summary>
    /// 添加一個回調事件
    /// </summary>
    /// <param name="key"></param>
    void AddEvent(GameEvent key)
    {
        eventDic.Add(key, delegate (object data) { });
    }

    /// <summary>
    /// 觸發事件
    /// </summary>
    /// <param name="key"></param>
    /// <param name="param"></param>
    public void TriggerEvent(GameEvent key,object param)
    {
        if (eventDic.ContainsKey(key))
        {
            eventDic[key](param);
        }
        else
        {
            Debug.LogError("沒有定義的事件:" + key);
        }
    }

    /// <summary>
    /// 綁定一個事件
    /// </summary>
    /// <param name="key">事件的key</param>
    /// <param name="attachEvent">事件的方法</param>
    public void AttachEvent(GameEvent key , CommonEvent attachEvent)
    {
        if (eventDic.ContainsKey(key))
        {
            eventDic[key] += attachEvent;
        }
        else
        {
            Debug.LogError("沒有定義的事件:" + key);
        }
    }

    /// <summary>
    /// 解綁一個事件
    /// </summary>
    /// <param name="key">事件的key</param>
    /// <param name="detachEvent">要解除的事件方法</param>
    public void DetachEvent(GameEvent key , CommonEvent detachEvent)
    {
        if (eventDic.ContainsKey(key))
        {
            eventDic[key] -= detachEvent;
        }
        else
        {
            Debug.LogError("沒有定義的事件:" + key);
        }
    }
}

——————2017.03.31更新——————————————
上文中的EventManager是一個多播委託。比如說我們遊戲中有多個怪物的實例,若我們觸發了怪物的死亡事件,那麼所有的怪物都會執行相應的死亡方法。此時,必須在怪物的死亡方法中做if條件判斷,來判斷自己是否達到了死亡條件。若不做判斷,則會立即死亡。
因此,在有多個實例的時候,在通知實例執行一定的方法時,必須設置好充分的條件判斷,這樣纔不會出問題。

發佈了36 篇原創文章 · 獲贊 29 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章