- Home /
Question by
Bowbowis · Jan 13, 2021 at 03:40 PM ·
rotationmovementquaternion
Rotation reversing for a single frame while turning.
I'm moving my player character using the following code:
public class PlayerController : MonoBehaviour
{
//Components
[SerializeField] Camera gameCamera;
[SerializeField] Rigidbody playerbody;
//Physics Constants
private float acc = 0.0703125f;
private float frc = 0.0703125f;
private float top = 9f;
//Inputs
public Vector3 moveInput;
public Vector3 localizedInput;
//Coroutines
Coroutine turnCoRt;
//On Move is called when activity from the Move InputAction is detected.
public void OnMove(InputValue value)
{
Vector2 rawInput = value.Get<Vector2>();
moveInput = new Vector3(rawInput.x, 0, rawInput.y);
if (moveInput != Vector3.zero)
{
//Get direction of input relative to the camera direction.
localizedInput = GetLocalizedInput();
if (turnCoRt != null) StopCoroutine(turnCoRt);
turnCoRt = StartCoroutine(Turn());
}
else
{
//Get direction of input relative to the camera direction.
localizedInput = Vector3.zero;
if (turnCoRt != null) StopCoroutine(turnCoRt);
}
}
//Update is called once per frame.
private void Update()
{
localizedInput = GetLocalizedInput();
}
// FixedUpdate is called once per fixed timestep frame.
void FixedUpdate()
{
if (moveInput != Vector3.zero)
{
Accelerate(acc);
}
else
{
Decelerate(frc);
}
}
void Accelerate(float acc)
{
if (playerbody.velocity.magnitude < top)
{
if (playerbody.velocity.magnitude + acc < top)
{
playerbody.AddForce(acc * localizedInput,
ForceMode.VelocityChange);
}
else
{
playerbody.AddForce((top - playerbody.velocity.magnitude) *
localizedInput, ForceMode.VelocityChange);
}
}
}
void Decelerate(float dec)
{
if (playerbody.velocity.magnitude > 0)
{
if (dec < playerbody.velocity.magnitude)
{
playerbody.AddForce(dec *
-playerbody.velocity.normalized,
ForceMode.VelocityChange);
}
else
{
playerbody.velocity = Vector3.zero;
}
}
}
Vector3 GetLocalizedInput ()
{
Vector3 camVector =
Vector3.ProjectOnPlane(gameCamera.transform.forward,
transform.up).normalized;
Quaternion camRotation =
Quaternion.FromToRotation(Vector3.forward, camVector);
Vector3 result = camRotation * moveInput;
return result;
}
IEnumerator Turn ()
{
for (float r = 0; r < 1; r += Time.deltaTime)
{
if (r > 1) r = 1;
transform.rotation = Quaternion.Slerp(Quaternion.LookRotation
(transform.forward, transform.up), Quaternion.LookRotation
(localizedInput, transform.up), r);
playerbody.velocity = transform.forward *
playerbody.velocity.magnitude;
yield return null;
}
for (; ; )
{
transform.rotation = Quaternion.LookRotation(localizedInput,
transform.up);
playerbody.velocity = transform.forward *
playerbody.velocity.magnitude;
yield return null;
}
}
}
This works for the most part but sometimes when holding left or right the rotation of the player character is reversed 180 degrees around the Y axis for a single frame. Can anybody help me figure out what is causing it?
Comment