Smooth FPS rotation with right/left arrow key
Hello community,
I am writing a simple fps controller and I am already stuck with movements. My design require rotation of the character to be performed with left/right arrows.
So my update function is:
void Update()
{
float _xMov = CrossPlatformInputManager.GetAxisRaw("Horizontal");
_xMov = Mathf.Abs(_xMov) > float.Epsilon ? _xMov : 0f;
m_CharacterTargetRot *= Quaternion.Euler(0f, _xMov * m_RotateSpeed, 0);
transform.localRotation = Quaternion.Slerp(transform.localRotation, m_CharacterTargetRot, m_SmoothRotation * Time.deltaTime);
}
By adjusting parameters RotateSpeed to 2 and SmoothRotation to 8 I can achieve a nice smooth rotation, but sometimes it gets "snappy" and "stiffy".
Does anyone knows how can I improve this (and maybe point out how uncorrectly am I using Slerp)?
Thank you very much,
Andrea
Answer by FortisVenaliter · Sep 28, 2017 at 07:43 PM
Yeah, I wouldn't use Slerp when you have a moving target. That's designed to smoothly move from two fixed points, so it doesn't surprise me that you end up with some unpredictable behaviour.
What you actually want is some basic calculus. Don't run away though, it is very basic. Instead of tracking only the angle, you want to track the angle and the angular velocity. When the user presses the buttons, they won't be changing their angle at all, they'll be changing their angular velocity. Then you just apply that velocity every frame to rotate the object. If the player is not pressing any rotation buttons, you apply dampening to the angular velocity to slow it back down to zero. After that, it's simply a matter of playing with the values until they stop feeling too loose or tight.
Thanks for the hint
I actually end up using the rigid body for handling the angular velocity by adding torque to it. I am satisfied on the result, although I think there is still a better way to do that.
I found it very useful in Unity 2017 using the Force$$anonymous$$ode.Acceleration, so you can ignore the mass in the calculation and can just write your code thinking about the angularVelocity magnitude.