Answers for "Collision misses - possibly not bullet through paper! (now with video)"
http://answers.unity.com/questions/263417/collision-misses-possibly-not-bullet-through-paper.html
The latest answers for the question "Collision misses - possibly not bullet through paper! (now with video)"Answer by Wolfram
http://answers.unity.com/answers/265444/view.html
First, let's simplify your testcase a bit:
- disable the sphere's gravity, it's irrelevant for the result
- to actually see what's going on, set the physics time scale to 0.1, it doesn't influence the computations
- now, to not wait for ages between events, set SpherePeriod to 0.2, and Position to -0.4
- disable the "static" setting on the cube - it's irrelevant for physics, but it makes things harder to see on Windows, since if it is on, the collider will be scaled, but the mesh will NOT be scaled
- set the Cube's scale.z to 0.01, to better see what's going on (but don't use your testcases then, or the value will be reset)
Now you can simply play with the **single** parameter Position.z to reproduce all the different behaviours you described - all other settings (Velocity, cube position, angles, collider scale, ...) are merely circumstantial. The only relevant fact is: "Where is the sphere located at a physics time step?"
Now, for the default timestep of 0.02, we get 50 physics steps per second, so for a velocity of z=10 the +z shift of the sphere will be 0.2 each frame.
Sphere and 0.01-scaled Cube will touch (the enter event) at radius/2+cubesize.z/2, which is z=-0.055, and similarly will completely have left the Cube (the exit event) at z=+0.055
Using only Position.z, the individual cases and situations occuring at a physics time step can now be broken down to:
- Sphere intersects after two time steps, the intersection occurs in the "front" half (see below): z=-0.455..-0.4 (which is -0.4-0.055)
- Sphere intersects after two time steps, the intersection occurs in the "back" half: z=-0.4..-0.345 (which is -0.4+0.055)
- Sphere does NOT intersect after two time steps: z=-0.345..-0.255 or -0.545..-0.455 (which are just the remaining intervals)
Note that:
- for all settings in the third case, the sphere always passes through; **this is just a case of "object is too fast for physics simulation, and therefore passes through"** (i.e., "bullet through paper")
- the Sphere also passes through in the second case
- the Sphere always bounces in the first case
- the Sphere bounces **if and *only* if** the rightmost hemisphere (the half "in front") lies at least partially within the left half of the cube (i.e., the interval -0.455..-0.4)
- the "Collision enter" is no longer reliable - needs further investigaion. On my machine (Windows 7 64bit), it will trigger only *once* in a regular(!) time interval of about 2 seconds (play with time scale here, the time interval when it triggers doesn't change much)
- the rigidbody.collisionDetection setting is irrelevant
You can verify the fourth (and most important) fact by playing with the collider scale of the cube: Over a value of 0.3, the sphere will *always* bounce. For smaller scales, the sphere will *only* bounce for the interval -i-(sphereScale.z+cubeScale.z)/2..-i, with i being a multiple of 0.2 (i.e., the z translation of the sphere per physics step). E.g., for the near-limit case cubeScale.z=0.29, the sphere will pass through for values between -0.4..-0.395 (watch out for floating point imprecisions, so use a slightly smaller interval, such as -0.3999..-0.3951)
So my **conclusion** at this point would be:
- rigidbody.collisionDetection does not work as expected, it always behaves as "discrete"
- for some reason, the PhysX engine does not test the *full* bounding box/collider volume, but only half of it (for both source and target)
- OnCollisionEnter and the PhysX collision detection use different bounds-/detection algorithms and are unrelated (which might makes sense if the one is provided by the PhysX engine, and the other is computed by the Unity engine)
- OnCollisionEnter is in itself buggy/unreliable
- we currently still need the workaround of DontGoThroughThings.js for fast objects to work correctly/better
I have not tried @whydoidoit's suggestion to do the actual parameter initializations in FixedUpdate() instead of in a Coroutine. This should be investigated, but I cannot spend more time on this, ATM.
EDIT: Now that I also read the last section of your question (*cough*), it seems rigidbody.collisionDetection is only evaluated if *both* objects have a rigidbody. I can see an improvement when setting the Sphere to "Continuous", but so far I haven't tried to quantify this. Also, the erratic behaviour which can be seen in your last video happens (only) if none of the objects is set to "Discrete", and at least one of the objects is set to "Continous dynamic".Mon, 11 Jun 2012 12:21:49 GMTWolfram