I have a "car" object with 2 colliders attached, a base and a top collider. Then I have a script attached to my car. I'm using OnTriggerEnter event to detect collisions with an invisible "Checkpoint". The problem is that OnTriggerEnter is called twice, I suppose because it is called either from the base collider and top collider. I want to check my object collider's name. OnTriggerEnter expose me with "other" collider; however, how can I test my collider's name?
You still CANNOT check for "source" trigger collider that triggers OnTriggerEnter, at least today or what I know at the time of writing (2020). But there is workaround.
For your racing game case
(This is 4 years after, you probably finished and mastered your cool racing game :). But I will include a specific answer to your question here, since it is manner for SO site, but I will keep it brief.)
Your racing game case is more trivial, since
OnTriggerEnter( Collider other ) offers information on other object, in this case the checkpoint being hit. You could identify checkpoint in some way, such as its name "Checkpoint1". Store and process it on your racing car player object, such as putting it in
HashSet, or anything, check to prevent duplication so that it run once.
If you need more detailed checkpoint object, such as passing this checkpoint will extend timer by +60sec. You could make a
Checkpoint MonoBehaviour Component and attach that to checkpoint object, add any properties you want. Then on player car when collide with these checkpoints,
GetComponent<Checkpoint>, process your checkpoint, again save it in
HashSet to prevent duplication.
For detecting trigger source
Now the fun part. First, you need to understand nature of how physics engine call those events. I recommend to skim over this official document also:
- Rigidbody documentation shows some insight about Compound Colliders.
- Collider documentation shows some insight about Static Collider vs Rigidbody Collider and how they interact.
The following are not stated in document but they are from what I observed:
- If 2 colliders are on same game object, it acts as compound colliders. OnTrigger*** will called once.
- If each collider is on different game object, such as parent-child (OP's case). OnTrigger*** will called once for each.
- First OnTrigger will called on-site of the source trigger (if there is script with OnTrigger*** on it),
- Then event will "bubble up" along the way and called on first RigidBody it reaches.
In both way, you still wont be able to know source trigger, because all events lead to one
OnTriggerEnter( Collider other ) which provide no source information at all.
You need to distribute relay/satellite scripts to each trigger collider. Some example or discussion, see:
This way, if we can catch OnTrigger*** first hand at source game object, we can know source trigger collider. Application such as detecting head shot, leg shot, arm shot is now possible.
To prevent event bubbling
Sometimes you don't want event to bubbling up. For example, player can use their attack (which parented to player object) to cut down the flying arrow. With normal event bubbling, when slash attack meets with arrow, signal will bubble to player's rigidbody as if his slash is extending player's own collision! (bad)
In such case, you don't want trigger event to bubble up to player game object. This is done by inserting kinematic rigidbody into slash attack, disconnecting it to form its own collision group.
You don't need to check the current object tag, since the OnCollisionEvent would only fire on the object you attached your monobehaviour script to.
Either your GameObject is bouncing and is registering two collision enter events in quick succession -- or it is colliding with at least 2 other colliders.
Tag your collider types so you can easily check to see what you are colliding with. Then you can add a debug statement in your OnCollisionEnter to see what is going on:
Debug.Log("Collided With: " + collider.gameObject.tag);