Unity事件系统

1.前言

Unity中事件/委托有着广泛的应用,本文通过封装一个简易的事件的系统,来统一管理消息的传递。此功能在简易应用或者事件较少的体现不出太好的作用,但是对于事件应用较多时,可以减少脚本之间的耦合。通过此事件系统架起不同脚本之间的桥梁,对于大量应用事件场景 中具有良好的效果。

2.事件系统

2.1 事件管理类

管理事件的注册与广播

using System;
using System.Collections.Generic;

namespace EventManager
{
    public delegate void ActionHandler(Message message);

    public class EventManager
    {
        #region Instance
        private static EventManager instance;

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

            return instance;
        }

        private EventManager() { }
        #endregion

        private Dictionary<string, ActionHandler> actions = new Dictionary<string, ActionHandler>();

        public void AddListener(string actionKey,ActionHandler action)
        {
            ActionHandler handler;
            bool exist = actions.TryGetValue(actionKey, out handler);

            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的新类来传递自定义参数。

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类型的参数来标记需要广播事件。此处可以改为枚举类型,后续可以优化。

namespace EventManager
{
    public class EventType
    {
        public readonly static string EVENTTYPE_METHOD1 = "EventType_Method1";
    }
}

3.应用案例

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);
        }
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值