Trigger in child object calls OnTriggerEnter in parent object

The parent object is a small cube with a box collider trigger to fit and a kinematic rigidbody. the child of that object is an empty with a sphere collider trigger that is larger than the box collider.

different scripts are in both parent and child with OnTriggerEnter functions.

expected behavior: when the larger sphere collider (a component of the child) is triggered without triggering the parent, OnTriggerEnter is called in the child object’s script.

observed behavior: when the larger sphere collider is triggered, OnTriggerEnter is called in both the parent and the child scripts.

Read the section labeled “Compound Colliders” on this page.

Long story short, collider shapes can’t be concave and the only way to accomplish something concave is to treat all convex colliders in children under a parent as if they are one shape, if the parent is the only one with a rigidbody. So, your parent is treating it as if its a complex shape, hence OnTriggerEnter in your parent is getting called.

Try this: give the child a kinematic rigidbody. This will separate it from the parent collision, but still allow it to be moved by the parent’s transform instead of physics.

However, be aware that if one touches or encompasses the other, now that they are seen as separate entities, a collision trigger will get registered between the two, even if it’s just at the beginning of the scene. They won’t bounce off each other since one is a trigger, but you may want to have each OnTriggerEnter function ignore the other Collider if it matches the tag of the other:

// in the child's function:
void OnTriggerEnter(Collider other)
{
    if (other.tag == "Parent's Tag")
        return; // do nothing

    Debug.Log("child goes ouch!");
}

// in the parent's function:
void OnTriggerEnter(Collider other)
{
    if (other.tag == "Child's Tag")
        return; // do nothing

    Debug.Log("parent goes ouch!");
}

I hope that helps!

Problem:

  • Parent with collider + rigidbody
  • Child with collider

Colliders will combine.

A solution:

  • Parent empty

  • Child with collider + rigidbody

  • Child with collider + follow script

     public GameObject followThisObject;
    
     void Update () {
     	transform.position = followThisObject.transform.position;
     }
    

I had to find another way to solve this because as a complete noob, I didn’t know about this so my entire code was designed to have a parent collider + RB + child object with a Trigger, just like you, I think. The proposed solution would have a really huge impact on the rest of the code.

To give you some context: I have my main actor and its child trigger. The trigger is to allow it to reach some objects close to it. I also needed to detect when the main’s collider entered a zone (a large trigger on the level) to call mainActor.DoMyStuff() and of course, both the child trigger and the collider were raising the OnTriggerEnter2D, therefore, calling the method twice.

So what I did is I added a tag on the parent and a different tag on the child trigger. Then I added the OnTriggerEnter2D on the level trigger (the zone I need the actor to enter) and there, I CompareTag to do something when it’s the parent that has entered (ignoring the child basically).
In your case, I guess you want to do something if the child trigger is reached by something so using this alternate solution you’d had to add a script to the trigger, maybe only to reference the main actor object. Then, in your bullet’s OnTriggerEnter, CompareTag and if it’s the trigger, call TriggerScript.MainReference.DoYourStuff();