Volume-casts are unreliable at very shallow angles/proximity

I was making a custom made character controller using shapecasts with capsule models that fit on a roblox character. However I’ve constantly had problems with the character phasing through walls when going at them almost parallel and then walking straight towards the wall.

Upon investigating further I realised the meshpart will almost always clip with objects slightly visually, which eventually ends up in a clip at a certain angle.
I experimented with a ball, block and a few capsule meshparts using all 3 volume casting methods. And if the angle is narrow enough even at some very thick “skin width” (like 0.5 studs), the player can clip through walls. This is quite frustrating with the current casting accuracy. As the player can technically move at any angle and clip through something even at a thick skin width of 1 stud.

Replication
Demonstrating the issue using walls with 0.1 degree and 0.01 degree rotation on the y axis.
Do note that replicating the issue in this showcase is done easiest when the rotations are zero or the skin width value is small (0.1-0.2 studs).
Move one of the “MoveThis” parts on the X axis on the sides of the walls precisely and the issue will occur.

Notes:

  • The capsules were created in blender and imported to Roblox.
  • “Skin width”: Is the number added on the cast distance, to account for the edge touches and floating point inaccuracy. Then subtracted from the hit distance before positioning the part.

I’ve been going insane over this for so long for why this happens, since I’ve followed a method used in a custom Unity controller from scratch, it works as intended as shown. From all the observation, I think the volume casts are too inaccurate for precise use cases unlike raycasts.

System info:
13th Gen Intel(R) Core™ i7-13700K
32.0 GB
NVIDIA GeForce RTX 4060 Ti

Expected behavior

Expected result: Parts should detect surfaces without any physical/visual intersection at any scale, fidelity or angle. And any follow-up casts should not phase through objects at a decently small skin width (at the very least 0.1 studs).

A private message is associated with this bug report

5 Likes

This is a bit late, but you aren’t implementing skin properly. Shifting back along the direction of the cast by a set amount doesn’t necessarily push you away from the object by that amount. For example, if you hit something at a 45-degree angle, moving back 0.5 only pushes you 0.25 away from the face you hit. Due to the lack of margins, after you get close enough, the subsequent casts will not hit the part you initially hit, causing you to phase through.

1 Like

Hey, it’s fine. I’ve been aware of how the skin was implemented, however the main issue wasn’t necessarily how it was implemented. I had been messing around alot to find a good enough solution and I realised the (likely) root cause of this issue. Roblox Vector3s are solely floating point numbers and combined with precise position changes does not go well, which was why these issues were happening. So it’s just a matter of how well you can deal with this floating point imprecision.

Every time you calculate a new position, there’s a small margin of error which shifts the position. If a player theoretically (or accidentally) walks precise enough (<0.005 deg) they can abuse this behavior. I was able to observe this behavior with standalone raycasts before trying to optimise this behavior.

Your solution sounds okay but it’s essentially the same as increasing the skin width from what I can tell, might try it though, since I probably won’t be using too complex terrain.

1 Like

On an informative side note, I tried dealing with this by optimising any unnecessary calculation to minimize imprecision errors. Also used :GetPartsInPart on a slightly smaller capsule attached to the colliding one to see if it’s clipping something. If it is, I just unanchor everything and let roblox physics handle the pushing. Has been working fine (for now)

1 Like

Thanks for the report! I filed a ticket in our internal database.

1 Like