Reverse Unity Event possible ?
Hey
I want to send an event when a game object gets destroyed when clicked, but i dont want to have one event for every game object because there will be like 50 of them :(
How can i make like a "reverse Unity Event" were i can listen on my game manger and send events when its get destroyed on OnDestroyed() ?
An "easy" way to do what you want, is to define an abstract class, heriting from $$anonymous$$onoBehaviour. Then, all your objects heriting from $$anonymous$$onoBehaviour, now herits from this custom class
Then , define delegate + event, and define the OnDestroy function
private void OnDestroy()
{
if( destroyEvent != null )
destroyEvent() ;
}
I'd make it a static event in that class. I'd also add a parameter "GameObject", so you can tell which of the calling objects is the one that fired it.
Answer by cjdev · Jan 17, 2016 at 11:46 PM
You can do this but I think you'll have to implement it in a custom class. By using delegates that send your GameObject as the parameter you can tell the EventManager what GameObject reference to send on to your handlers. Because the GameObject isn't actually deleted until the end of the frame you can do what you need to in those methods. If you don't mind a block of code, this is what a basic event handler with a parameter might look like:
using System;
using System.Collections.Generic;
public enum EVENT { OnDeath, MyEvent2 }; // ... Other events
public static class EventManager
{
// Stores the delegates that get called when an event is fired
private static Dictionary<EVENT, Delegate> eventTable
= new Dictionary<EVENT, Delegate>();
// Adds a delegate to get called for a specific event
// The parameter type of the method added has to be specified
public static void AddHandler<T>(EVENT evnt, Action<T> action)
{
if (!eventTable.ContainsKey(evnt)) eventTable[evnt] = action;
else eventTable[evnt] = (Action<T>)eventTable[evnt] + action;
}
// Fires the event with the included parameter
public static void Broadcast<T>(EVENT evnt, T param)
{
Delegate d;
if (eventTable.TryGetValue(evnt, out d))
{
Action<T> action = d as Action<T>;
if (action != null) action(param);
}
}
}
That will let you both add handlers for your events and then broadcast them, in your case from the OnDestroy of the GameObject. The Action type, if you haven't seen it, is just a modern delegate that doesn't require the declaration. The 'T' parameter is a generic and kind of a variable that lets you put in any type. This is how you would use the EventManager above:
using UnityEngine;
public class DyingObject: MonoBehaviour {
void OnDestroy()
{
EventManager.Broadcast(EVENT.OnDeath, gameObject);
}
}
using UnityEngine;
public class ListeningClass: MonoBehaviour {
void Start()
{
// This is the reference to whatever object is going to be dying
GameObject myDyingGO = GameObject.Find("yourDyingGameObject");
// Adds a lambda expression, a generic method, that calls your method
EventManager.AddHandler<GameObject>(EVENT.OnDeath,
(x) => DoSomethingOnDeath(myDyingGO));
Destroy(myDyingGO);
// Output: "Foo"
}
private void DoSomethingOnDeath(GameObject go)
{
// You can call this method for all of your dying GameObjects
if (go.name == "yourDyingGameObject")
Debug.Log("Foo");
}
}
Because you're using generics here you can also use this EventManager for any other type: ints, floats, custom classes. This gives you a lot more flexibility when it comes to cross-class communication. If I understood your question right I think this should solve it, if not let me know.