在使用游戏引擎开发游戏时,要用到的事件有很多,除了系统事件、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);
}
}
}
}