- Home /
OnTriggerEnter/Stay/Exit2D() Not Working Consistantly
I currently have Unity 5.3.4f1 installed, and I'm having some difficulty with getting consistent results from OnTriggerEnter/Stay/Exit2D.
I have a player character and an enemy character, each have a rigid body and collider. Both have Kinematic unchecked, and I have tried different combinations of interpolate, sleep and collision detection modes.
In my environment, I have ground tiles each with a BoxCollider2D and no RigidBody.
As a child to the player character, I have a GameObject with a BoxCollider2D set as a trigger and a simple attack script. In the hero's animation, I enable the collider during attacks, then disable it after the attack. The script attached to the child is simply:
void OnTriggerEnter2D(Collider2D target) {Debug.Log("Enter" + target.gameObject.name);} void OnTriggerStay2D(Collider2D target) {Debug.Log("Stay" + target.gameObject.name);} void OnTriggerExit2D(Collider2D target) {Debug.Log("Exit" + target.gameObject.name);}
When I strike at the enemy, it never registers an Enter, Stay or Exit call. I have tested many times, tweaking every parameter I can find. Not once.
When I strike at a ground tile, it registers Enter and Stay once each. It occasionally registers Exit once. However, if I strike the same ground tile again, it will not register any Enter, Stay or Exit calls. Even if I hit another tile and come back, any tile that's been hit won't issue calls until I stop playback.
I feel like I must be making some kind of really dumb rookie mistake, so if anyone can provide some advice on how to get more consistent results I'd really appreciate it! Thanks in advance.
I was able to get more consistent results by applying a rigid body to the child object that had the attack trigger collider. It doesn't seem to matter whether that or the target are set to $$anonymous$$inematic.
Even with that, I'm not sure whether to accept my own answer because it doesn't explain why I was getting such inconsistent results before. In 5.1 I had created a similar test, and in that case I was getting consistent Stay calls, inconsistent Exit calls and no Enter calls.
Is this just something I'm going to have to double check after every editor update?
Are there any consequence or best practices to keep in $$anonymous$$d when putting a rigid body on the child of an object with a rigid body?
Answer by Bunny83 · May 23, 2016 at 11:11 PM
The trigger messages are generated by the rigidbody component. A collider (no matter if it's a trigger or a normal collider) can't detect collisions / intersections on their own. Only Rigidbodies can. The messages should be generated on the gameobject that has the rigidbody attached as all child colliders are used as compound colliders.
By attaching a kinematic rigidbody to your child object you allow the child to generate trigger messages on it's own. See the tables at the bottom of this page which object can collide or generate trigger messages. In any case at least one rigidbody is required.
To answer your follow up question:
Are there any consequence or best practices to keep in mind when putting a rigid body on the child of an object with a rigid body?
Yes, if you attach a rigidbody as a child of any other moving object, this rigidbody should be kinematic. Non-kinematic rigidbodies are simulated in worldspace and should therefore never be a child of another moving object as this movement will disturbe the simulation of the rigidbody.
Thanks for the clarification!
The only thing that still leaves me a bit confused is, why was it generating any hits at all? The table on your link says that static triggers shouldn't be connecting with static colliders. So if the script and collider on the child object shouldn't be able to send/receive OnTriggers through the parent's RigidBody, why was it registering hits on the static ground objects?
Were the static ground colliders viewing the the trigger as a rigidbody trigger because of its parent? Despite that the trigger didn't seem to think of itself as a rigidbody trigger?
OnTrigger and OnCollision messages are always send to both participants. They are always generated by a Rigidbody. The object that has a rigidbody will send the message to the object the rigidbody is attached to, even when a child collider / trigger is responsible for the event. If you hit a static collider (so it doesn't have a rigidbody on it's own level or on any parent) the object with the collider will get the message as well.
I mainly was referring to the 3D physics as i barely have used the 2D stuff. But it seems to be quite similar there.