I’ve built a very simple game (based on the old “labyrinth” toy.
When the game starts, the ball (rigidbody, affected by gravity, made of metal) hits drops onto the tiltable maze (made of wood) it works just fine unless you keep the mouse completely still until the ball lands – in which case the ball gets stuck.
Put simply: ball (rigid body with sphere collider) drops onto cube. If you move cube before ball drops, it works. If you don’t, ball gets stuck in position.
To replicate:
Create a scene with a ball above a cube.
Make the ball a rigid body.
Press PLAY. The ball will fall onto the cube and come to rest. Now move the cube – the ball is stuck.
Workaround:
Making the base a rigidbody and kinematic seems to solve the problem. Still it seems that the program should either always work or never without doing this.
That’s the solution, not the workaround. If anything is moving, and you need it to react to physics, it needs to be a rigidbody, period, or you will have problems. And if you don’t want it to move, then it needs to be kinematic.
(Don’t worry. I did the same thing in one of my early test games. My marble fell through my spinning platform.)
Basically, if you want a moving object to interact with physics, it needs to have a rigidbody. (colliding against static stuff doesn’t count as ‘interacting’ right here).
If physics is moving the object, it should not be kinematic. If you are moving it from scripts or animations, it should be kinematic.
Thanks but this doesn’t explain why everything works fine if I move the (non-rigidbody) before the collision occurs.
I.e. by moving the object I appear to give it the qualities of a rigidbody. Until it moves it lacks them. If nothing else, this seems to indicate that Physics overhead is being paid for any moving object.
Collision detection of meshes computationally expensive, so physics engines attempt to optimize it heavily by letting rigidbodies fall asleep quickly. Thus they only have to perform collision detection on the objects which are actually in motion.
When no forces are applied to an object from scripts, and it falls to rest due to gravity and collisions, the rigidbody will fall asleep. When you add forces to it again via scripting, it will wake up again and perform collision detection. Also when a rigidbody comes close to it, collision detection will be performed.
However static colliders do not do this. Static colliders never wake up other rigidibodies even if they move. So if you have a collider which you want to move, and you expect it to work correctly with other rigidbodies. Then you need to add a rigidbody to it and make it kinematic.
But my point was that the non rigidbody worked fine as long as it was moved before the ball hit it. i.e. a plain, ordinary cube (which is what it happened to be) was interacting with a rigidbody once it was moved.
(As an aside: I was actually surprised that it worked without having a rigidbody assigned to it. I expected to have to add a rigid body to the maze to make it work… and only ended up having to do it to fix this bug.)
So the physics engine is treating ordinary objects as rigid bodies when it shouldn’t be – and presumably incurring an overhead by doing so.
To replicate:
Create a ball … make it a rigid body, and lift it a bit into the air.
Create a cube below the sphere.
Press Play:
The sphere lands on the cube and sticks (why doesn’t it just pass through?)
Now stick this script on it:
function Update () {
transform.Rotate(1,1,1);
}
Press play.
Now the cube behaves like a rigid body. (It isn’t.)
Let me try to make a bit clearer, why this is the intended behaviour.
This is only a matter of sleeping, not about the position or rotation of the collider. When you move a static collider, it will move to where you tell it to move, however it will not wake up any other rigidbodies.
If you move a static collider while a rigidbody is not sleeping, the rigidbody of course will do collisions wherever the static collider currently is.
Thus the only difference between static colliders and kinematic rigidbodies in that regard is that the static collider won’t wake up rigidbodies when moving. The difference is NOT the position rotation of the static collider.
Thus: While the sphere has not fallen asleep, the collider will perform the exact same collision detection as if it was a kinematic rigidbody.
When the sphere has fallen asleep, it will in the case of the kinematic rigidbody wake up the rigidbody. In the case of the static collider it will not wake up the rigidbody.
How do I make a cube that rigidbodies won’t bump into? I assumed that this would be the “default” state, but I don’t see what I can “turn off” to make the cube “ethereal”.
Just remove the component. In the inspector you have a context menu on the title of that component, it shows you a menu entry called Remove Component. You can also do this from a script if you like.
ah. i figured something along that you had a cube that you didn’t want to fall through a ground plane but wanted rigidbodies to ignore it. if it doesn’t have to collide with anything just remove the collider component like joe said.