Generic event subscription between gameObjects?

Hi,

I’m trying to figure out to have multiple colliders in an object hierarchy and communicate with a main script on the parent object to execute some code accordingly.

I come from JavaScript and reactive programming and it would have been pretty straightforward, i would have added an event emitter on the child object, linked the child object to the main object using a serialized field and subscribed to the event in the main script with a callback. I don’t know how to do something similar in Unity.

I’ve seen that there is an event system but it seems to be more global and it’s more application-wide.

Thanks

You can do pretty much exactly what you’re describing.

A quick & easy way is to create a small MonoBehavior script that invokes a UnityEvent upon detecting a collision:

public class CollisionDetector : MonoBehavior {
   [SerializeField] private UnityEvent<Collision> onCollisionEnter;

   private void OnCollisionEnter(Collision collision) => onCollisionEnter.Invoke(collision);
}

You can then attach this script to all of your child colliders and, in the inspector, add an event listener to call a function on your main script for each of them.

One thing worth noting though is that if your main GameObject has a Rigidbody attached to it, then this is essentially already done internally. The Rigidbody will listen for collisions in all child colliders, and the various OnCollision.../OnTrigger... callbacks will be invoked on the same GameObject that the Rigidbody is attached to.

1 Like

Thanks a lot.

I had some trouble because a default UnityEvent can’t take a parameter, you have to create your own event class.

Here is my final code:

using UnityEngine;
using UnityEngine.Events;

namespace CustomEvents {

    [System.Serializable]
    public class Collider2DEvent : UnityEvent <Collider2D> {}
}
using UnityEngine;
using CustomEvents;

public class CollisionTriggerEvent : MonoBehaviour {

    [SerializeField] Collider2DEvent collisionEvent;

    void OnTriggerEnter2D(Collider2D other) {
        this.collisionEvent.Invoke(other);
    }
}

Right, my bad. They added support for generic UnityEvent serialization starting from some newer version of Unity; not sure which version it was added in.

BroadcastMessage() is another option to call methods on all child objects.