In-case anyone comes across this and is having the same issues, I believe a workable solution. I’m still refining it but I’ll provide a brief overview below. Later on I’ll share a more in-depth explanation.
In my custom CharacterControllerDriver, instead of just setting the CharacterController (from now on referred to as CC) to the camera position on the Y plane every fixed update, I instead use Physics.CapsuleCast in the Y plane direction towards the camera to determine if moving the CC would cause it to overlap with something. If there is no hit, I update the CC center as described in the above video. If there is a hit, as along as its no too close, then I will move the CC just enough so that it doesn’t overlap with the object it would have otherwise hit. As this doesn’t actually stop the camera from clipping into objects, I then perform a raycast from the camera’s base position (which I define as the World X and Z values of the CC’s center, and the World Y value of the camera) towards the camera’s world position. If there is a hit, I know the camera is passing through something and can either black it out or push the CC back a bit using the move function.
This method (in experience so far) is actually pretty good for preventing/handling wall clipping without any of the frustrating stuff like the super jumpy pushbacks that happen when you do clip a wall, or the game breaking stuff like walking through a wall and then having your CC snap to position, effectively letting you phase through things.
There are two caveats I wanted to mention.
Firstly, it’s important to move the points for the capsule cast opposite to the direction of the cast by a small amount (I’ve found 1cm to be plenty). Then you need to add the amount you pushed the capsule back to the maxDistance. This is because I found that the volume taken up by the defined capsule overlaps or even just touches a collider, then the CapsuleCast won’t recognise a hit with that object. And then you get super odd results.
Second, if the camera and CC are separated (say because you’re leaning over a virtual table) and then you try to rotate using a TurnProvider (I’ve not checked with a snap turn provider but it happens with the continuous), then very weird and things happen, and you get teleported all over the place. I’m not exactly sure why this is, but I’ve found that the solution (as hacky as it is) is to recreate the turn provider, and in the “TurnRig” function, before the line xrOrigin.RotateAroundCameraUsingOriginUp(turnAmount);
store the world position of the CC center, then after that line is called, restore the CC’s center. It Looks something like this
var worldCenter = transform.TransformPoint(CC.center);
xrOrigin.RotateAroundCameraUsingOriginUp(turnAmount);
CC.center = transform.InverseTransformPoint(worldCenter );
Not exactly why this works but it does. (Also this assumes you’ve got this custom turn provider on the XROrigin and that you have a reference to the CC already stored.)
I hope this helps someone. I know its very basic. I hope to have a far more thorough explanation later on. Please feel free to ask any questions if you have them.