I've been stuck trying to implement continuous collision detection/response for my character controller for a while now, and been trying different methods. I recently tried a method described in this video at around 51:34:
Here's my simplified implementation in pseudocode:
Move(movement)
{
// This is the position we want to move to
targetPosition = currentPosition + movement
// Find all surfaces obstructing the movement
// Treat each contact as a planar constraint (normal of contact = normal of plane)
constraints = CapsuleSweep(currentPosition to targetPosition)
while (all constraints are not satisfied)
{
for (c in constraints)
{
if (c is already satisfied)
{
Continue the for-loop to the next constraint
}
else
{
projectedPosition = projection of capsule onto c
// Move the capsule slightly further away from c to create breathing room for any sweeps in the next frame
projectedPosition += tolerance
// Do another sweep to potentially find new constraints
newConstraints = CapsuleSweep(targetPosition to projectedPosition)
if (any new constraints are found)
{
constraints += newConstraints
Break out of the for loop to start again with the updated list of constraints
}
else
{
// Update targetPosition because we now want to try to solve this new position
targetPosition = projectedPosition
Continue the for-loop to the next constraint
}
}
}
}
// After all constraints are satisfied, update the actual position of the character
// Remember that targetPosition doesn't necessarily refer to the initial position we wanted to move to at the start of the frame as it gets updated to satisfy all constraints
currentPosition = targetPosition
}
It works great except that it starts to jitter when stuck in a corner or when walking into a shrinking corridor. The jittering sometimes even causes it to go through walls. Here are some videos showing it: https://imgur.com/a/pssrWE1
The thing is that I know what's causing the jittering - it's the fact that I add a tolerance after solving each constraint, since any future sweeps won't pick up a wall if the sweep starts exactly on the edge of the wall. I'll try to explain why this causes jittering. Consider this image:
![](https://uploads.gamedev.net/forums/monthly_2022_06/303f8736d9a04ab38d5b69b17a10f3f1.image.png)
It's really messy but couldn't show it in a easier way. So imagine that we want to move from the blue circle to the red one. We then project onto the wall that was in the way (shown by the first purple arrow). We then find the new wall and project out of that one too. This continues until we reach the green circle (for simplicity only two of the steps are shown). Because we are adding a small tolerance each time though, the final position will be slightly off the initial position. This causes the jittering. In some rare cases the green circle will also be close enough to the opposing wall that a future sweep might miss it, meaning that we go through the wall.
If I didn't add any extra tolerance the final position would lie perfectly close to both walls, meaning no jitter, but then we would go through the walls on the next frame because the sweep wouldn't detect them.
If I bring the tolerance down the jittering decreases somewhat, but the issue with going through walls remains.
I have no idea on how to fix this, so some help would be greatly appreciated. (and sorry for a lot of text)