I have a problem that I did not managed to solved for about two days now.
I made a simple third person character controller for the (W, S, A, D) keys using a character from mixamo, the problem is that when I stop pressing the W key for example the character keeps walking forward for half a second more like if it was sliding on ice if that makes any sense.
Does anyone familiar with this problem and knows how to solve it?
The PlayerController.cs
public class PlayerController : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
[SerializeField] float rotationSpeed = 1000f;
Quaternion targetRotation;
CameraController cameraController;
private void Awake() {
cameraController = Camera.main.GetComponent<CameraController>();
}
private void Update() {
float horizontal = Input.GetAxis("Horizontal");
float vartical = Input.GetAxis("Vertical");
float moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vartical));
var moveInput = new Vector3(horizontal, 0, vartical).normalized;
var moveDirection = cameraController.PlanerRotation * moveInput;
if (moveAmount > 0) {
transform.position += moveSpeed * Time.deltaTime * moveDirection;
targetRotation = Quaternion.LookRotation(moveDirection);
}
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
rotationSpeed * Time.deltaTime);
}
}
And this is the camera controller if thats relavant
public class CameraController : MonoBehaviour
{
[SerializeField] Transform target;
[SerializeField] float sensitivityX;
[SerializeField] float sensitivityY;
[SerializeField] float distance = 3;
[SerializeField] float minVarticalClamp = -10;
[SerializeField] float maxVarticalClamp = 45;
[SerializeField] Vector2 framingOffset;
[SerializeField] bool invertX;
float rotationX;
float rotationY;
float invertXVal;
private void Start() {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
private void Update() {
invertXVal = (invertX) ? -1 : 1;
rotationX += Input.GetAxis("Mouse Y") * invertXVal * sensitivityX;
rotationX = Mathf.Clamp(rotationX, minVarticalClamp, maxVarticalClamp);
rotationY += Input.GetAxis("Mouse X") * sensitivityY;
var targetRotation = Quaternion.Euler(rotationX, rotationY, 0);
var focusPosition = target.position + new Vector3(framingOffset.x, framingOffset.y);
transform.position = focusPosition - targetRotation * new Vector3(0, 0, distance);
transform.rotation = targetRotation;
}
public Quaternion PlanerRotation => Quaternion.Euler(0, rotationY, 0);
}
Your problem is occurring because this function is smoothed.
Input.GetAxis()
This means it simulates how a joystick works; when you release the button it smoothly transitions to zero instead of happening instantly.
If you don't want this behaviour you can use this function instead.
Input.GetAxisRaw()
This will behave like a button and apply no smoothing.
Worth noting that smoothing might be what you want, you might just be handling it badly.
Something like this
private void Update() {
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
float nonNormalInput = new Vector3(horizontal, 0, vertical);
var moveInput = nonNormalInput.normalized;
var moveDirection = cameraController.PlanerRotation * moveInput;
if (nonNormalInput.magnitude > 0) {
transform.position += moveSpeed * Time.deltaTime * moveDirection * nonNormalInput.magnitude;
targetRotation = Quaternion.LookRotation(moveDirection);
}
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
rotationSpeed * Time.deltaTime);
}
Would give you the benefit of the smoothing, or you can totally ignore it using Input.GetAxisRaw()
. I usually use Input.GetAxisRaw()
.