使用Unity的UnityEvent实现一个简单的事件系统

2 篇文章 0 订阅

在使用游戏引擎开发游戏时,要用到的事件有很多,除了系统事件、UI事件还有开发者自定义事件,所以我就想做一个自定义事件类,作用:管理事件以及一般的功能,接下来我就使用Unity的UnityEvent来实现一个不可以停止事件系统

下面就是实现部分,我使用了Unity里面的UnityEventBase和UnityEvent,UnityEventBase是UnityEvent的父类,以此关系实现一个事件的注册、订阅、取消订阅、广播的操作,在这里,使用了泛型和重载,目的是为了迎合多种需求,也没有装箱拆箱的操作。

要使用此事件系统,首先创建一个类,继承UnityEvent或者UnityEvent,比如:

//测试1事件类
public class Test1Event : UnityEvent { }
//测试2事件类
public class Test2Event : UnityEvent<int> { }

订阅事件:

//订阅测试1事件
eventSystem.Add<Test1Event>(OnTest1);
//订阅测试2事件
eventSystem.Add<Test2Event , int>(OnTest2);

删除事件:

//删除测试1事件
eventSystem.Remove<Test1Event>(OnTest1);
//删除测试2事件
eventSystem.Remove<Test2Event , int>(OnTest2);

广播:

//广播测试1事件
eventSystem.Run<Test1Event>();
//广播测试2事件
eventSystem.Run<Test2Event , int>(1);

注意:

//订阅事件时请使用函数名,不要使用Lamba 表达式,使用Lamba 表达式会导致移除操作不成功,进而出现bug
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace Game.Event
{
    public class EventSystem
    {
        private Dictionary<string, UnityEventBase> allEvents;

        public EventSystem()
        {
            allEvents = new Dictionary<string, UnityEventBase>();
        }

        private T1 Add<T1>() where T1 : UnityEventBase, new()
        {
            UnityEventBase baseEvent;

            Type type = typeof(T1);

            if (allEvents.TryGetValue(type.Name, out baseEvent))
            {
                return (T1)baseEvent;
            }
            else
            {
                T1 t = new T1();
                allEvents.Add(type.Name, t);
                return t;
            }
        }

        public void Add<T1>(UnityAction call) where T1 : UnityEvent, new()
        {
            Add<T1>().AddListener(call);
        }

        public void Add<T1, T2>(UnityAction<T2> call) where T1 : UnityEvent<T2>, new()
        {
            Add<T1>().AddListener(call);
        }

        public void Add<T1, T2, T3>(UnityAction<T2, T3> call) where T1 : UnityEvent<T2, T3>, new()
        {
            Add<T1>().AddListener(call);
        }

        public void Add<T1, T2, T3, T4>(UnityAction<T2, T3, T4> call) where T1 : UnityEvent<T2, T3, T4>, new()
        {
            Add<T1>().AddListener(call);
        }

        public T1 GetEvent<T1>() where T1 : UnityEventBase, new()
        {
            UnityEventBase baseEvent;

            Type type = typeof(T1);

            if (!allEvents.TryGetValue(type.Name, out baseEvent))
            {
                Debug.LogError($"{type.Name}此事件没有注册过");
                return null;
            }

            if (baseEvent == null)
            {
                Debug.LogError($"{type.Name}此事件没有任何人绑定");
                return null;
            }

            return (T1)baseEvent;
        }

        public bool Remove<T1>(UnityAction call) where T1 : UnityEvent, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.RemoveListener(call);
                return true;
            }
            return false;
        }

        public bool Remove<T1, T2>(UnityAction<T2> call) where T1 : UnityEvent<T2>, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.RemoveListener(call);
                return true;
            }
            return false;
        }

        public bool Remove<T1, T2, T3>(UnityAction<T2, T3> call) where T1 : UnityEvent<T2, T3>, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.RemoveListener(call);
                return true;
            }
            return false;
        }

        public bool Remove<T1, T2, T3, T4>(UnityAction<T2, T3, T4> call) where T1 : UnityEvent<T2, T3, T4>, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.RemoveListener(call);
                return true;
            }
            return false;
        }

        public void Run<T1>() where T1 : UnityEvent, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.Invoke();
            }
        }

        public void Run<T1, T2>(T2 t2) where T1 : UnityEvent<T2>, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.Invoke(t2);
            }
        }

        public void Run<T1, T2, T3>(T2 t2, T3 t3) where T1 : UnityEvent<T2, T3>, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.Invoke(t2, t3);
            }
        }

        public void Run<T1, T2, T3, T4>(T2 t2, T3 t3, T4 t4) where T1 : UnityEvent<T2, T3, T4>, new()
        {
            T1 baseEvent = GetEvent<T1>();
            if (baseEvent != null)
            {
                baseEvent.Invoke(t2, t3, t4);
            }
        }
    }
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值