OnTriggerEnter doesn't work if the colliding object is not moving. Translating it by (0,0,0) fixes it. What's the problem?
I have a problem getting a OnTriggerEnter event using a moving object colliding with a non moving object. Let me explain:
I have two objects in the scene. The first one is my bullet, which is a cube with a Box Collider (Is Trigger checked).
This bullet is moving towards a target with the simple following script:
void Update () {
transform.Translate(0, 1*Time.deltaTime, 0);
}
It has an overriden OnTriggerEnter which does nothing except outputing a log message:
void OnTriggerEnter(Collider otherObject){
Debug.Log("Collided!");
}
The target is also a cube, with a Box Collider and a RigidBody (Is Kinematic checked). It is not moving, so there is nothing updating the transform.
Now here is the strange thing, with this setup only, the bullet does not trigger the event when it collides with the target. However, if I add a script to my target doing nothing but translating its transform with a null vector, as follows:
void Update () {
transform.Translate(0, 0, 0);
}
it works and I do get the log message saying "Collided".
Does anybody know what the problem is? Am I doing something wrong? Does causing the transform to refresh by translating it activate the rigidbody or something?
Edit: it also works without the null translate if I add a RigidBody (IsKinetic checked) on the Bullet.
The debug message is on the bullet which has a trigger Box Collider.
hmm, it does indeed sound odd, i would think it is because your trigger is stationary, but i've got stationary triggers in a few of the games i've made as well, and i dont have this issue.
could you try going into edit -> project settings -> physics and then set sleep and sleep angular velocity to 0, see if that changes anything.
Tell me if that changes anything.
edit: doing that will make physics update everything every frame, even if its stationary, its a resource hog.
also, what happens if you have the debug on the trigger?
I am not sure of the terms you use, so just to be clear:
Bullet == moving object, box collider with trigger (this object should receive the trigger event with the debug message), no rigidbody
Target == stationary object, box collider without trigger, has a rigidbody
Now if I add a rigidbody on the bullet, it works.
Concerning the sleep velocities, it's still the same even if I set them to 0
Answer by Kid Canuck · Apr 22, 2013 at 01:11 AM
I'm having a similar issue. I am spawning an object with a sphere collider trigger in front of my character (capsule collider, rigidbody). The spawned object does a bit of its own setup (when it is spawned, it will fall until it is on the ground, then set the radius of the collider). If I am not moving, and I spawn the object, I do not get any OnCollider messages at all (even though the capsule is completely inside the sphere). If I move my character at all, I get the OnTriggerEnter message and it works fine.
It seems to me that if neither object is moving*, it will not even check for trigger / collider interactions.
My fix was, when I turned on the collider and set the size for it, I waited 1 frame and then 'nudged' the object myTransform.position = myTransform.position + Vector3.zero;
This forces the physics system to respond, and even though it did not actually move, it processes the colliders and notices the interaction. Seems likely to me it's an optimization based on the pretense that if 2 things are not moving they cannot hit each other.
I hope this helps others with similar issues.
This is HUG$$anonymous$$ I wish it was better documented, because I just realized it's the source of almost all trigger problem's I've had in unity...
This... helped a lot.
I tried to forcefully wake up the rigid body every frame but it didn't work.
Adding rigid bodies to every object you want to pick up works, but performance takes a hit.
Awesome Solution ;D
Thanks for the trick! I just tried with Unity 5.35, a + Vector3.zero didn't work in this version, but + Vector3.right x 0.001f worked (and - Vector3.right x 0.001f in the next frame to ensure consistency).
Answer by OddSlice1 · Jun 24, 2017 at 05:12 AM
I had a similar problem, I spawned in an object and wanted to know if it was colliding with another. Both are kinematic RigidBodies 2D with 2DColliders and the spawned in object wouldn't call its OnTriggerEnter2D() function. The way I solved it was by changing the Rigidbodies 2D sleep options to "Never Sleep". I believe that in the default state, "Start Asleep" an object "Wakes up" and starts checking for collisions only when it starts to move, thus the "translate (0,0,0)" thing working.
Answer by IMTRIGGERHAPPY9 · Oct 06, 2011 at 02:19 PM
Try using OnTriggerStay that should work perfetly
I just tried but I have the same result as using OnTriggerEnter...
Answer by JimRustler · Feb 06, 2014 at 01:11 AM
I believe the problem is with the way that Unity checks for collisions. It doesnt make sense to check every single object for collisions constantly so they most likely only check the objects that have moved that frame. Thats why translating by (0,0,0) works because it marks it as "moved" for that frame.
Your answer
Follow this Question
Related Questions
OnTriggerEnter no longer works 1 Answer
How to Make A Character Stop At Wall? 0 Answers
Rigidbody2D figits when pushed against an object. 0 Answers
Rigidbody randomly going through collider 1 Answer
Freezed object loses it's collider 1 Answer