I would stick with UnityEvent
’s with this. I’m not sure how you were using them before resorting to Action
s, but I set up a small scene with a “spawner” that spawns one bomb and adds a listener to the UnityEvent
that the Bomb controller has. The bomb controller will destroy itself after 3 seconds, then its OnDestroy()
will trigger, invoking the BombDisarmed
UnityEvent
.
The was UnityEvent
s work is that you need to add listeners (which are your methods you want triggered), and then invoke the UnityEvent
when you want it to.
In the spawner, i add my listener once I instantiate the bomb. Then in the bomb’s OnDestroy
, I invoke the UnityEvent
, which the triggers HandleBombDisarmed()
from the spawner.
If you want to go one step further, you can include the BombController in the listener by implementing your own UnityEvent
class. Then you can access information about each bomb when they are disarmed. Here is the documentation on UnityEvent
Unity - Scripting API: UnityEvent<T0>
Basically, you create a class that extends UnityEvent, and you do nothing else with it! You can see at the bottom of BombController that I created one (I added System.Serializable on it so that it shows up in the inspector, check it out!).
Then to use this new UnityEvent
type, use it just like a normal UnityEvent
, the only catch is, the listener you give it must have the same parameter type at , and when you call Invoke()
, it needs an argument with the same type as well.
I implemented both types of UnityEvent
s in the code. "BombDisarmed"
is the normal way you asked for. And "CoolBombDisarmed"
is the the going a step further and letting you pass the bomb object to the method.
(Sorry for the novel, I don’t answer these much!)
SpawnerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnerController : MonoBehaviour
{
public GameObject BombPrefab;
void Start ()
{
GameObject bomb = Instantiate(BombPrefab);
BombController bombController = bomb.GetComponent<BombController>();
bombController.BombDisarmed.AddListener(HandleBombDisarmed);
bombController.CoolBombDisarmed.AddListener(HandleCoolBombDisarmed);
}
public void HandleBombDisarmed()
{
Debug.Log("Bomb disarmed");
}
public void HandleCoolBombDisarmed(BombController bomb)
{
Debug.Log("Bomb disarmed. Its name was " + bomb.gameObject.name);
}
}
BombController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class BombController : MonoBehaviour
{
public UnityEvent BombDisarmed;
public BombDisarmedEvent CoolBombDisarmed;
// Use this for initialization
void Start ()
{
StartCoroutine(BlowUp());
}
private void OnDestroy()
{
BombDisarmed.Invoke();
CoolBombDisarmed.Invoke(this);
}
IEnumerator BlowUp()
{
yield return new WaitForSeconds(3.0f);
Destroy(this.gameObject);
}
}
[System.Serializable]
public class BombDisarmedEvent : UnityEvent<BombController>
{
}
Worked great, thanks!
– Gingergingerbread