带有委托而不是UnityEvent的Unity EventManager

我正在使用UnityEvent寻找此Manager的

c#委托版本。我不想使用它,因为UnityEvent在大多数时候都比C#事件慢。

关于如何实现这一点的任何线索?

回答:

您可以使用Action实际上是这样声明的委托:

namespace System

{

public delegate void Action();

}

从使用委托的名称空间UnityAction替换所有with 。Action``System

全部thisEvent.AddListener(listener);替换为thisEvent += listener;

全部thisEvent.RemoveListener(listener);替换为 thisEvent -= listener;

这是Unity 原始 版本的修改版本,可EventManager移植为使用委托/动作。

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class EventManager : MonoBehaviour

{

private Dictionary<string, Action> eventDictionary;

private static EventManager eventManager;

public static EventManager instance

{

get

{

if (!eventManager)

{

eventManager = FindObjectOfType(typeof(EventManager)) as EventManager;

if (!eventManager)

{

Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene.");

}

else

{

eventManager.Init();

}

}

return eventManager;

}

}

void Init()

{

if (eventDictionary == null)

{

eventDictionary = new Dictionary<string, Action>();

}

}

public static void StartListening(string eventName, Action listener)

{

Action thisEvent;

if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))

{

//Add more event to the existing one

thisEvent += listener;

//Update the Dictionary

instance.eventDictionary[eventName] = thisEvent;

}

else

{

//Add event to the Dictionary for the first time

thisEvent += listener;

instance.eventDictionary.Add(eventName, thisEvent);

}

}

public static void StopListening(string eventName, Action listener)

{

if (eventManager == null) return;

Action thisEvent;

if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))

{

//Remove event from the existing one

thisEvent -= listener;

//Update the Dictionary

instance.eventDictionary[eventName] = thisEvent;

}

}

public static void TriggerEvent(string eventName)

{

Action thisEvent = null;

if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))

{

thisEvent.Invoke();

// OR USE instance.eventDictionary[eventName]();

}

}

}

测试脚本:

下面的测试脚本通过每2秒触发一次事件来测试事件。

public class TestScript: MonoBehaviour

{

private Action someListener;

void Awake()

{

someListener = new Action(SomeFunction);

StartCoroutine(invokeTest());

}

IEnumerator invokeTest()

{

WaitForSeconds waitTime = new WaitForSeconds(2);

while (true)

{

yield return waitTime;

EventManager.TriggerEvent("test");

yield return waitTime;

EventManager.TriggerEvent("Spawn");

yield return waitTime;

EventManager.TriggerEvent("Destroy");

}

}

void OnEnable()

{

EventManager.StartListening("test", someListener);

EventManager.StartListening("Spawn", SomeOtherFunction);

EventManager.StartListening("Destroy", SomeThirdFunction);

}

void OnDisable()

{

EventManager.StopListening("test", someListener);

EventManager.StopListening("Spawn", SomeOtherFunction);

EventManager.StopListening("Destroy", SomeThirdFunction);

}

void SomeFunction()

{

Debug.Log("Some Function was called!");

}

void SomeOtherFunction()

{

Debug.Log("Some Other Function was called!");

}

void SomeThirdFunction()

{

Debug.Log("Some Third Function was called!");

}

}


从其他问题来看,大多数人都在问如何支持参数。这里是。您可以使用class/

struct作为参数,然后将要传递的所有变量添加到此类/结构中的函数中。我将EventParam举一个例子。随意EventParam在代码末尾添加/删除要在事件结构中传递的变量。

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class EventManager : MonoBehaviour

{

private Dictionary<string, Action<EventParam>> eventDictionary;

private static EventManager eventManager;

public static EventManager instance

{

get

{

if (!eventManager)

{

eventManager = FindObjectOfType(typeof(EventManager)) as EventManager;

if (!eventManager)

{

Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene.");

}

else

{

eventManager.Init();

}

}

return eventManager;

}

}

void Init()

{

if (eventDictionary == null)

{

eventDictionary = new Dictionary<string, Action<EventParam>>();

}

}

public static void StartListening(string eventName, Action<EventParam> listener)

{

Action<EventParam> thisEvent;

if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))

{

//Add more event to the existing one

thisEvent += listener;

//Update the Dictionary

instance.eventDictionary[eventName] = thisEvent;

}

else

{

//Add event to the Dictionary for the first time

thisEvent += listener;

instance.eventDictionary.Add(eventName, thisEvent);

}

}

public static void StopListening(string eventName, Action<EventParam> listener)

{

if (eventManager == null) return;

Action<EventParam> thisEvent;

if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))

{

//Remove event from the existing one

thisEvent -= listener;

//Update the Dictionary

instance.eventDictionary[eventName] = thisEvent;

}

}

public static void TriggerEvent(string eventName, EventParam eventParam)

{

Action<EventParam> thisEvent = null;

if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))

{

thisEvent.Invoke(eventParam);

// OR USE instance.eventDictionary[eventName](eventParam);

}

}

}

//Re-usable structure/ Can be a class to. Add all parameters you need inside it

public struct EventParam

{

public string param1;

public int param2;

public float param3;

public bool param4;

}

测试脚本:

public class Test : MonoBehaviour

{

private Action<EventParam> someListener1;

private Action<EventParam> someListener2;

private Action<EventParam> someListener3;

void Awake()

{

someListener1 = new Action<EventParam>(SomeFunction);

someListener2 = new Action<EventParam>(SomeOtherFunction);

someListener3 = new Action<EventParam>(SomeThirdFunction);

StartCoroutine(invokeTest());

}

IEnumerator invokeTest()

{

WaitForSeconds waitTime = new WaitForSeconds(0.5f);

//Create parameter to pass to the event

EventParam eventParam = new EventParam();

eventParam.param1 = "Hello";

eventParam.param2 = 99;

eventParam.param3 = 43.4f;

eventParam.param4 = true;

while (true)

{

yield return waitTime;

EventManager.TriggerEvent("test", eventParam);

yield return waitTime;

EventManager.TriggerEvent("Spawn", eventParam);

yield return waitTime;

EventManager.TriggerEvent("Destroy", eventParam);

}

}

void OnEnable()

{

//Register With Action variable

EventManager.StartListening("test", someListener1);

EventManager.StartListening("Spawn", someListener2);

EventManager.StartListening("Destroy", someListener3);

//OR Register Directly to function

EventManager.StartListening("test", SomeFunction);

EventManager.StartListening("Spawn", SomeOtherFunction);

EventManager.StartListening("Destroy", SomeThirdFunction);

}

void OnDisable()

{

//Un-Register With Action variable

EventManager.StopListening("test", someListener1);

EventManager.StopListening("Spawn", someListener2);

EventManager.StopListening("Destroy", someListener3);

//OR Un-Register Directly to function

EventManager.StopListening("test", SomeFunction);

EventManager.StopListening("Spawn", SomeOtherFunction);

EventManager.StopListening("Destroy", SomeThirdFunction);

}

void SomeFunction(EventParam eventParam)

{

Debug.Log("Some Function was called!");

}

void SomeOtherFunction(EventParam eventParam)

{

Debug.Log("Some Other Function was called!");

}

void SomeThirdFunction(EventParam eventParam)

{

Debug.Log("Some Third Function was called!");

}

}

以上是 带有委托而不是UnityEvent的Unity EventManager 的全部内容, 来源链接: utcz.com/qa/427443.html

回到顶部