zoukankan      html  css  js  c++  java
  • 工具类——EventManager

    EventManager

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.SceneManagement;
    
    /// <summary>
    /// 事件类型枚举
    /// </summary>
    public enum EVENT_TYPE
    {
        SPAWBLUEARMY,
        SPAWBLUEARMYFINISH,
        CLEARSCENE,
    };
    
    public class EventManager : SingletonMonoBehaviour<EventManager>
    {
    
        #region variables
    
        //事件委托
        public delegate void OnEvent(EVENT_TYPE Event_Type, Component Sender, object Param = null);
    
        //存储每个事件类型下的订阅
        private Dictionary<EVENT_TYPE, List<OnEvent>> Listeners = new Dictionary<EVENT_TYPE, List<OnEvent>>();
        #endregion
        //-----------------------------------------------------------
        #region methods
    
        void Awake() {
            SceneManager.sceneLoaded += OnSceneLoaded;
        }
        /// <summary>
        /// 添加订阅
        /// </summary>
    
        public void AddListener(EVENT_TYPE Event_Type, OnEvent Listener)
        {
            List<OnEvent> ListenList = null;
    
            if (Listeners.TryGetValue(Event_Type, out ListenList))
            {
                //List exists, so add new item
                ListenList.Add(Listener);
                return;
            }
    
            ListenList = new List<OnEvent>();
            ListenList.Add(Listener);
            Listeners.Add(Event_Type, ListenList);
        }
        //-----------------------------------------------------------
        /// <summary>
        /// 分发事件,调用该事件类型下的所有订阅者的委托方法
        /// </summary>
        public void PostNotification(EVENT_TYPE Event_Type, Component Sender, object Param = null)
        {
            List<OnEvent> ListenList = null;
    
            if (!Listeners.TryGetValue(Event_Type, out ListenList))
                return;
    
            for (int i = 0; i < ListenList.Count; i++)
            {
                if (!ListenList[i].Equals(null))
                    ListenList[i](Event_Type, Sender, Param);
            }
        }
        //-----------------------------------------------------------
        public void RemoveEvent(EVENT_TYPE Event_Type)
        {
            Listeners.Remove(Event_Type);
        }
        //-----------------------------------------------------------
        //移除订阅字典中无效订阅者
        public void RemoveRedundancies()
        {
            Dictionary<EVENT_TYPE, List<OnEvent>> TmpListeners = new Dictionary<EVENT_TYPE, List<OnEvent>>();
    
            foreach (KeyValuePair<EVENT_TYPE, List<OnEvent>> Item in Listeners)
            {
                for (int i = Item.Value.Count - 1; i >= 0; i--)
                {
                    if (Item.Value[i].Equals(null))
                        Item.Value.RemoveAt(i);
                }
    
                if (Item.Value.Count > 0)
                    TmpListeners.Add(Item.Key, Item.Value);
            }
    
            Listeners = TmpListeners;
        }
    
        //单例下换场景不会销毁,因此需要在场景加载后清除无效的订阅
        void OnSceneLoaded()
        {
            RemoveRedundancies();
        }
        //-----------------------------------------------------------
        #endregion
    }
    

    使用案例

    using UnityEngine;
    using System.Collections;
    
    public class EnemyObject : MonoBehaviour
    {
    	//-------------------------------------------------------
    	//C# accessors for private variables
    	public int Health
    	{
    		get{return _health;}
    		set
    		{
    			//Clamp health between 0-100
    			_health = Mathf.Clamp(value, 0, 100);
    
    			//Post notification - health has been changed
    			EventManager.Instance.PostNotification(EVENT_TYPE.HEALTH_CHANGE, this, _health);
    		}
    	}
    	//-------------------------------------------------------
    	public int Ammo
    	{
    		get{return _ammo;}
    		set
    		{
    			//Clamp ammo between 0-50
    			_ammo = Mathf.Clamp(value,0,50);
    
    			//Post notification - ammo has been changed
    			EventManager.Instance.PostNotification(EVENT_TYPE.AMMO_CHANGE, this, _health);
    		}
    	}
    	//-------------------------------------------------------
    	//Internal variables for health and ammo
    	private int _health = 100;
    	private int _ammo = 50;
    	//-------------------------------------------------------
    	//Called at start-up
    	void Start()
    	{
    		//Add myself as listener for health change events
    		EventManager.Instance.AddListener(EVENT_TYPE.HEALTH_CHANGE, OnEvent);
    	}
    	//-------------------------------------------------------
    	// Update is called once per frame
    	void Update () 
    	{
    		//If you press space bar, the health is reduce
    		if(Input.GetKeyDown(KeyCode.Space))
    		{
    			//Take some damage of space bar  press
    			Health -= 5;
    		}
    	}
    	//-------------------------------------------------------
    	//Called when events happen
    	public void OnEvent(EVENT_TYPE Event_Type, Component Sender, object Param = null)
    	{
    		//Detect event type
    		switch(Event_Type)
    		{
    			case EVENT_TYPE.HEALTH_CHANGE:
    				OnHealthChange(Sender, (int)Param);
    			break;
    		}
    	}
    	//-------------------------------------------------------
    	//Function called when health changes
    	void OnHealthChange(Component Enemy, int NewHealth)
    	{
    		//If health has changed of this object
    		if(this.GetInstanceID() != Enemy.GetInstanceID()) return;
    
    		Debug.Log ("Object: " + gameObject.name +  " Health is: " + NewHealth.ToString());
    	}
    	//-------------------------------------------------------
    }
    
    
  • 相关阅读:
    Python操作文件和目录
    ffmpeg命令简单使用
    【转载】一个简单的爬虫:爬取豆瓣的热门电影的信息
    【转载】正则表达式re.S的用法
    linux用户添加
    SQL语句update修改数据库字段
    linux命令之cp
    linux命令——tree命令
    Linux磁盘管理
    Python资源安装过程出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))…………
  • 原文地址:https://www.cnblogs.com/Firepad-magic/p/13040285.html
Copyright © 2011-2022 走看看