I know that the teacher of this course probably removed the existing colliders and put a new collider on the same Game Object as the script where the collider is referenced to make it easier to teach probably. But what if you want to reuse the existing colliders. Isn’t there a way to access child colliders? Would that be very complicated?
You can access them with GetComponentOnChildren()
but they will not execute the callbacks. The script with the callback has to be on the same game object as the collider
That answers my question. Thanks.
I then decided that I didn’t like the less precise-looking collider that the teacher used and remembered that you can also use OnCollisionEnter(Collison collison) to do the same thing and it works with child colliders. I also decided that I prefer to have the player Game object disable command on the player Game object instead of the asteroid or asteroids.
One thing you can do is to put a specialized script on the child collider objects that get a collision and relay that collision information to the script in the parent Gameobject…
I was actually considering this after my response. A specialized script that would handle the callbacks and invoke events.
Something like
public class CollisionEventArgs : EventArgs
{
public Collision Collision { get; }
public CollisionEventArgs(Collision collision) => Collision = collision;
}
public class TriggerEventArgs : EventArgs
{
public Collider Collider { get; }
public TriggerEventArgs(Collider collider) => Collider = collider;
}
public class CollisionHandler : MonoBehaviour
{
public event EventHandler<CollisionEventArgs> CollisionEnter;
public event EventHandler<CollisionEventArgs> CollisionStay;
public event EventHandler<CollisionEventArgs> CollisionExit;
public event EventHandler<TriggerEventArgs> TriggerEnter;
public event EventHandler<TriggerEventArgs> TriggerStay;
public event EventHandler<TriggerEventArgs> TriggerExit;
private void OnCollisionEnter(Collision collision)
=> CollisionEnter?.Invoke(this, new CollisionEventArgs(collision));
private void OnCollisionStay(Collision collision)
=> CollisionStay?.Invoke(this, new CollisionEventArgs(collision));
private void OnCollisionExit(Collision collision)
=> CollisionExit?.Invoke(this, new CollisionEventArgs(collision));
private void OnTriggerEnter(Collider other)
=> TriggerEnter?.Invoke(this, new TriggerEventArgs(collider));
private void OnTriggerStay(Collider other)
=> TriggerStay?.Invoke(this, new TriggerEventArgs(collider));
private void OnTriggerExit(Collider other)
=> TriggerExit?.Invoke(this, new TriggerEventArgs(collider));
}
I can’t help but feel like something is not going to work the way I expect it to, though
Impressive! I just did the code below to use the existing colliders:
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
gameObject.SetActive(false);
}
}
Or if you want the Asteroid to handle the code I found you can do this:
using UnityEngine;
public class Asteroid : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
collision.gameObject.SetActive(false);
}
}
These seemed to work fine for me.
Custom EventArg classes don’t make much sense when only passing one argument. I would do it this way:
public class CollisionHandler : MonoBehaviour
{
public event EventHandler<Collision> CollisionEnter;
public event EventHandler<Collision> CollisionStay;
public event EventHandler<Collision> CollisionExit;
public event EventHandler<Collider> TriggerEnter;
public event EventHandler<Collider> TriggerStay;
public event EventHandler<Collider> TriggerExit;
private void OnCollisionEnter(Collision collision) => CollisionEnter?.Invoke(this, collision);
//etc
}
If you planned on leaving room to add additional parameters, then creating a custom EventArgs makes sense (because refactoring is easier), but it’s not likely that this will be the case here.
Yeah, that is true. I just personally prefer to always have EventArgs
but you are right; it can just be the colliders/collisions.