基于Unity的事件管理者

事件管理者


个人使用的事件管理者,用于项目中的事件分发,以增加代码的灵活性。

事件

由于本人习惯,本着“多一事不如少一事“”的原则,使用的是程序库中自带的事件EventHandler

using System.Runtime.InteropServices;

namespace System
{
    [ComVisible(true)]
    public delegate void EventHandler(object sender, EventArgs e);
}

其中,参数EventArgs类,也是程序库中自带的:

using System.Runtime.InteropServices;

namespace System
{
    [ComVisible(true)]
    public class EventArgs
    {
        public static readonly EventArgs Empty;

        public EventArgs();
    }
}

管理者

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

/// <summary>
/// 事件管理者
/// </summary>
public class EventManager : BaseManager<EventManager>
{
    Dictionary<GameObject, Dictionary<Type, EventHandler>> m_dic = new Dictionary<GameObject, Dictionary<Type, EventHandler>>();

    /// <summary>
    /// 增加事件
    /// </summary>
    /// <typeparam name="T">事件的参数类</typeparam>
    /// <param name="owner">拥有对象</param>
    /// <param name="eh">事件</param>
    public void AddEvent<T>(GameObject owner, EventHandler eh) where T : EventArgs
    {
        if (!m_dic.ContainsKey(owner))
        {
            m_dic[owner] = new Dictionary<Type, EventHandler>();
        }
        Type type = typeof(T);
        if (m_dic[owner].ContainsKey(type))
        {
            m_dic[owner][type] += eh;
        }
        else
        {
            m_dic[owner][type] = eh;
        }
    }

    /// <summary>
    /// 触发事件
    /// </summary>
    /// <typeparam name="T">事件的参数类</typeparam>
    /// <param name="owner">拥有对象</param>
    /// <param name="sender">事件的参数</param>
    /// <param name="t">事件的参数</param>
    public void TriggerEvent<T>(GameObject owner, object sender, T t) where T : EventArgs
    {
        if (m_dic.ContainsKey(owner))
        {
            Type type = typeof(T);
            if (m_dic[owner].ContainsKey(type))
            {
                m_dic[owner][type].Invoke(sender, t);
            }
        }
    }

    /// <summary>
    /// 移除事件
    /// </summary>
    /// <typeparam name="T">事件的参数类</typeparam>
    /// <param name="owner">拥有对象</param>
    /// <param name="eh">事件</param>
    public void RemoveEvent<T>(GameObject owner, EventHandler eh) where T : EventArgs
    {
        if (m_dic.ContainsKey(owner))
        {
            Type type = typeof(T);
            if (m_dic[owner].ContainsKey(type))
            {
                m_dic[owner][type] -= eh;
            }
        }
    }
}

该类为单例,继承的便是我自己编写的一个单例父类,之前有篇专门记录的文章:可点击查看相关文章
在代码中,有一个两重字典,用于准确确定到我们所要用到的事件。第一重为GameObject类型,是场景中的一个物体;第二重为一个衍生自EventArgs类型的类的类型。

使用

使用这个事件管理者时,先写一个与事件EventHandler结构一样的一个函数:

public void TestEvent(object sender, EventArgs e)
{

}

然后再创建一个衍生自EventArgs类型的类:

public class TestEventArgs : EventArgs
{

}

然后将函数中所要真正用到的参数,以字段的形式创建于该类中。再只需要在函数中,将EventArgs类的参数转换成对应类型(如例:TestEventArgs)

public void TestEvent(object sender, EventArgs e)
{
	TestEventArgs tea=(TestEventArgs)e;
}

便可以获取到真正传入的所需要的参数了。在其之后便可编写执行逻辑。
使用事件前先将其添加入事件管理者:

EventManager.GetInstance().AddEvent<TestEventArgs>(gameObject, TestEvent);

触发事件时:

EventManager.GetInstance().TriggerEvent(gameObject, 0new TestEventArgs());

其中的数字0,便是函数的第1个object类型的参数,如有需要,可自行更改。
最后不需要其事件时,可以将其在管理者中删除:

EventManager.GetInstance().RemoveEvent<TestEventArgs>(gameObject, TestEvent);
发布了20 篇原创文章 · 获赞 1 · 访问量 937

猜你喜欢

转载自blog.csdn.net/f_957995490/article/details/103654376