The problem is thus. When an object is moving extremely fast relative to another, relatively thin object, it can pass straight through without colliding. Here’s a visual demonstration of how and why this happens:
In this example, the ball starts on the far right in frame 1. In frame 2 it has moved a lot closer to the wall, and in frame 3, it has moved past the wall. The ball moves so fast that there is no frame where it intersects the wall, and so the engine fails to detect any collision between them at all.
Now, unity has a solution to this problem, purportedly. Continuous collision detection. I’m not sure exactly how unity implements this, but i can tell you how it should work (and how i hope it does). I designed this solution independantly myself a few years ago, but i’m sure i’m not the first one to think of it.
Firstly, remember that every object has a rectangular bounding box. Even a sphere. So physically our projectile can be represented like this:
Note the grey box around.
Now. As far as i understand, the basic principle of continuous collision detection is enabling functionally infinite and perfect collision resolution, on a per-object basis. This will obviously be more computationally expensive, but a lot more efficient compared to other solutions such as increasing the resolution of the entire simulation (by adjusting the fixed timestep). When done right, no object should ever pass through a wall without colliding, no matter how thin the wall, and no matter how small the bullet.
Here’s how:
In this above example, we take the bounding box of the projectile, and onionskin it along the velocity path. Creating a chain of them where each exactly touches the previous one with no overlap. Here, frames 2.6 and 3.6 represent the final position of the object on frame 2 and 3 respectively. But rather than jumping there, the object would be iterated through however many steps of its own length (along the velocity vector) it would take to reach the target point. So during frame 2, you do 2.1, 2.2, 2.3, etc in order. At each step, check for collision with colliders around it.
In this way, any obstacle in the path of the movement, no matter how small or thin, will be detected and properly collided with, and passing through walls becomes impossible. Fixed timestep becomes irrelevant, and an object of any size will resolve correctly (however the cost/processing time will rise linearly as the projectile’s size drops) There’s probably far more efficient ways to do this too, with raycasting maybe.
This is how i believe continuous collision detection should work, it’s how it would work if i implemented it, and it’s how i 'm hoping, that it DOES work. But is that correct, or not?
According to the documentation here: Unity - Scripting API: Rigidbody.collisionDetectionMode
To implement continuous collision detection, i have to put ContinuousDynamic on my projectiles, and Continuous on objects i want to be able to intercept them. So that’s What i’ve done.
Now i’m standing here flinging cannonballs at a paper-thin wall. I’ve got it rigged up that the firing force of the ball charges up (infinitely, with no upper limit) as i hold the mouse button, and fires on release. At lowish speeds, the cannonball bounces off the wall, as i’d expect. At moderate speeds, they embed into the wall, and stick there like spitballs. At high speeds they just fly right on through and don’t give a fuck.
I don’t know what this option is doing, but it doesnt seem to be working