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.
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.
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.