- Home /
The question is answered, right answer was accepted
EventManager with parameters
So I'm using the EventManager code from this Unity tutorial, I figured it would help clean up my beginner project. Although I would like to be able to pass a parameter with UnityAction.
In the tutorial, every function that is added as a listener is one without any parameters.
I was hoping I could find a way to do this without too much trouble, but I spent a while researching it, and it seems like the most popular answer is to use delegates/Action instead... I tried modifying it myself, and I feel like I was close, but I'm lost at the moment.
I'd rather avoid that extra work of rewriting what I've done, so here I am.
For an example of what I'd like to do, I was hoping that I could do something like this in my code, it's invalid code, but it's basically what I'm trying to achieve:
void Awake()
{
someListener = new UnityAction (SomeFunction); //<---Can't do this
}
void SomeFunction(GameObject someObject) //<--- Because this has a parameter
{
doSomething();
}
Below you can see what I mean, where the original examples are.
The EventTest.cs:
public class EventTest : MonoBehaviour
{
private UnityAction someListener;
void Awake ()
{
someListener = new UnityAction (SomeFunction); //<---This works,
}
void OnEnable ()
{
EventManager.StartListening ("test", someListener);
}
void SomeFunction () //<---Because no parameter here!
{
Debug.Log ("Some Function was called!");
}
}
And they call the TriggerEvent in another class, so it's not directly referencing EventTest:
public class EventTriggerTest : MonoBehaviour {
void Update () {
if (Input.GetKeyDown ("q"))
{
EventManager.TriggerEvent ("test"); //No need to reference EventTest! Hooray!
}
}
And here is the EventManager.cs:
public class EventManager : MonoBehaviour {
private Dictionary <string, UnityEvent> eventDictionary;
private static EventManager eventManager;
public static EventManager instance
{
get
{
if (!eventManager)
{
eventManager = FindObjectOfType (typeof (EventManager)) as EventManager;
if (!eventManager)
Debug.LogError ("Need 1 active EventManger script on GameObject in your scene.");
else
eventManager.Init();
}
return eventManager;
}
}
void Init ()
{
if (eventDictionary == null)
eventDictionary = new Dictionary<string, UnityEvent>();
}
public static void StartListening (string eventName, UnityAction listener)
{
UnityEvent thisEvent = null;
if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
thisEvent.AddListener (listener);
else
{
thisEvent = new UnityEvent ();
thisEvent.AddListener (listener);
instance.eventDictionary.Add (eventName, thisEvent);
}
}
public static void StopListening (string eventName, UnityAction listener)
{
if (eventManager == null) return;
UnityEvent thisEvent = null;
if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
thisEvent.RemoveListener (listener);
}
public static void TriggerEvent (string eventName)
{
UnityEvent thisEvent = null;
if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
thisEvent.Invoke ();
}
}
Answer by DrSharky · Sep 11, 2018 at 01:07 AM
I essentially found the answer to my question here, under the "With Parameter" section. Although it's using Action instead of UnityEvent, it's basically the same thing: https://stackoverflow.com/questions/42034245/unity-eventmanager-with-delegate-instead-of-unityevent
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);
}
}
}