Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Resolved Generic event subscription between gameObjects?

Discussion in 'Scripting' started by Magnesium, Jan 15, 2021.

  1. Magnesium

    Magnesium

    Joined:
    Sep 14, 2014
    Posts:
    179
    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
     
  2. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    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:
    Code (CSharp):
    1. public class CollisionDetector : MonoBehavior {
    2.    [SerializeField] private UnityEvent<Collision> onCollisionEnter;
    3.  
    4.    private void OnCollisionEnter(Collision collision) => onCollisionEnter.Invoke(collision);
    5. }
    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.
     
    PraetorBlue likes this.
  3. Magnesium

    Magnesium

    Joined:
    Sep 14, 2014
    Posts:
    179
    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:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3.  
    4. namespace CustomEvents {
    5.  
    6.     [System.Serializable]
    7.     public class Collider2DEvent : UnityEvent <Collider2D> {}
    8. }
    9.  
    Code (CSharp):
    1. using UnityEngine;
    2. using CustomEvents;
    3.  
    4. public class CollisionTriggerEvent : MonoBehaviour {
    5.  
    6.     [SerializeField] Collider2DEvent collisionEvent;
    7.  
    8.     void OnTriggerEnter2D(Collider2D other) {
    9.         this.collisionEvent.Invoke(other);
    10.     }
    11. }
    12.  
     
  4. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    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.
     
  5. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    691
    BroadcastMessage() is another option to call methods on all child objects.