When my player walks around a circular planet everything works well, but when my planet is a shape like a cube or a dodecahedron, even with smoothed edges, my character jitters if I walk slowly on the edge.
That is because I raycast downward and set my characters rotation to be perpendicular with the normal. If im on the edge, the ray hits a different side of the shape than the one I stand on, causing my player to rotate to that new side, even if the angle between the face I stand on and the one I hit is 179°. So when My character rotates, the face I hit with the ray becomes the one I was standing on before, causing me to rotate back and forth between 2 faces.
Here is a beautiful scheme of what I mean:
I tried using SphereCast instead of Raycast, but it didn't work. How can I limit the back and forth rotations ?
Here is the script for the raycast:
void Update(){
...
if (Physics.Raycast(rayStart, GetDirection(IsGrounded, GravityChangeHitPoint), out RaycastHit hit, Mathf.Infinity, layerMask))
{
Debug.DrawLine(transform.position, hit.point,Color.red);
Quaternion matchSurface;
if (GravityChangeHitPoint == GravityCenter.position)
matchSurface = PlayerLookRotation(transform.forward, hit.normal);
else
matchSurface = PlayerLookRotation(transform.forward, -GetDirection(IsGrounded, GravityChangeHitPoint));
Quaternion cam = Quaternion.Euler(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
if (!IsGrounded)
transform.rotation = Quaternion.Lerp(transform.rotation, matchSurface, Time.deltaTime * damping) * cam;
else
transform.rotation = matchSurface * cam;
}
}
Quaternion PlayerLookRotation(Vector3 approximateForward, Vector3 exactUp)
{
Quaternion zToUp = Quaternion.LookRotation(exactUp, -approximateForward);
Quaternion yToZ = Quaternion.Euler(90, 0, 0);
return zToUp * yToZ;
}