Я бы посоветовал не использовать здесь углы в максимально возможной степени. Вместо этого вы можете использовать точечные продукты между правым направлением камеры и местным направлением проигрывателя, чтобы определить, какое местное направление наиболее соответствует прямому направлению камеры. Объяснение в комментариях.
void Right()
{
float dotThreshold = Mathf.Sin(Mathf.PI * 0.25f);
// Take the dot products between the camera's right and
// each direction from the player.
// Either exactly one dot product will exceed this threshold
// (sin 45 degrees) or two will equal it.
// Either way, when we see one dot product >= the threshold,
// we know what direction we should face.
Vector3 camRight = mainCam.transform.right;
if(Vector3.Dot(camRight, transform.right) >= dotThreshold)
{
// camera's right ~ player's right
animator.Play("StandQuarterTurnRight");
}
else if(Vector3.Dot(camRight, -transform.forward) >= dotThreshold)
{
// camera's right ~ player's back
animator.Play("StandHalfTurnRight");
}
else if(Vector3.Dot(camRight, -transform.right) >= dotThreshold)
{
// camera's right ~ player's left
animator.Play("StandQuarterTurnLeft");
}
else
{
// camera's right ~ player's forward
float forw = Input.GetAxis("Horizontal");
if (forw > 0.5f && !Input.GetKey(KeyCode.LeftShift)) forw = 0.5f;
else if (forw < -0.5f && !Input.GetKey(KeyCode.LeftShift)) forw = -0.5f;
animator.SetFloat("Speed", forw);
}
}
Если вы не можете предположить, что плеер и камера имеют одинаковое направление оси y, вы должны проецироваться в одну плоскость, как в вопросе:
void Right()
{
float dotThreshold = Mathf.Sin(Mathf.PI * 0.25f);
// Take the dot products between the camera's right and
// each direction from the player.
// Either exactly one dot product will exceed this threshold
// (sin 45 degrees) or two will equal it.
// Either way, when we see one dot product >= the threshold,
// we know what direction we should face.
Vector3 camRight = Vector3.ProjectOnPlane(mainCam.transform.right, Vector3.up);
Vector3 playerRight = Vector3.ProjectOnPlane(transform.right, Vector3.up);
Vector3 playerForward = Vector3.ProjectOnPlane(transform.forward, Vector3.up);
if(Vector3.Dot(camRight, playerRight) >= dotThreshold)
{
// camera's right ~ player's right
animator.Play("StandQuarterTurnRight");
}
else if(Vector3.Dot(camRight, -playerForward) >= dotThreshold)
{
// camera's right ~ player's back
animator.Play("StandHalfTurnRight");
}
else if(Vector3.Dot(camRight, -playerRight) >= dotThreshold)
{
// camera's right ~ player's left
animator.Play("StandQuarterTurnLeft");
}
else
{
// camera's right ~ player's forward
float forw = Input.GetAxis("Horizontal");
if (forw > 0.5f && !Input.GetKey(KeyCode.LeftShift)) forw = 0.5f;
else if (forw < -0.5f && !Input.GetKey(KeyCode.LeftShift)) forw = -0.5f;
animator.SetFloat("Speed", forw);
}
}