The question is answered, right answer was accepted
How can i smooth out my Camera / Player Movement
Hello guys i started with unity 2 months ago and i want to make my camera / player movement smoother but i don't know how and it doesn't feel that good. Here is my Code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player_Movement : MonoBehaviour
{
[Header("Movement")]
private CharacterController cc;
public Animator animator;
public Transform groundCheck;
public Transform orientation;
public LayerMask groundMask;
Vector2 dir;
Vector3 velocity;
bool isGrounded;
bool isWalking;
public float moveSpeed = 5.5f;
public float gravity = -9.81f;
public float groundDistance = 0.1f;
[Header("Camera Movement")]
public Transform cam;
private Transform playerbody;
public float mouseSensitivity;
private float x,y,xRotation;
void Awake()
{
cc = GetComponent<CharacterController>();
playerbody = this.transform;
}
public void MoveThePlayer(InputAction.CallbackContext ctx)
{
dir = ctx.ReadValue<Vector2>();
if(dir.x >0 || dir.x <0 || dir.y >0 || dir.y <0)
{
isWalking = true;
}
else
{
isWalking = false;
}
}
public void MoveTheCamera(InputAction.CallbackContext ctx)
{
Vector2 camDir = ctx.ReadValue<Vector2>();
x = camDir.x * mouseSensitivity;
y = camDir.y * mouseSensitivity;
}
void Update()
{
if(Hello_World.Instance.paused == false)
{
PlayerMove();
CameraMove();
animator.SetBool("Walking", isWalking);
}
}
void PlayerMove()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y <0)
{
velocity.y = -0.5f;
}
Vector3 moveDir = orientation.right * dir.x + orientation.forward * dir.y;
velocity.y += gravity * Time.deltaTime;
cc.Move(moveDir * moveSpeed * Time.deltaTime);
cc.Move(velocity * Time.deltaTime);
}
void CameraMove()
{
xRotation -= y;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
cam.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
playerbody.Rotate(Vector3.up * x);
}
}
Answer by DenisIsDenis · Jun 20, 2021 at 05:41 AM
Lerp
, LerpUnclamped
, MoveToward
and RotateTowards
exist to smooth out the movement of the player, or the camera, or even just change any float value. For many Unity types, all of the above features are already implemented. In your script, you need to slightly change the movement and rotation functions and add a few variables.
Quaternion playerRotation; // [ADDED]
public float lookingSmoothTime = 3; // [ADDED]
public float movingSmoothTime = 3; // [ADDED]
private Vector2 dirCurrent; // [ADDED]
void Awake()
{
cc = GetComponent<CharacterController>();
playerRotation = transform.rotation; // [ADDED]
playerbody = this.transform;
}
public void MoveThePlayer(InputAction.CallbackContext ctx)
{
dir = ctx.ReadValue<Vector2>();
dirCurrent.x = Mathf.Lerp(dirCurrent.x, dir.x, Time.deltaTime * movingSmoothTime); // [ADDED]
dirCurrent.y = Mathf.Lerp(dirCurrent.y, dir.y, Time.deltaTime * movingSmoothTime); // [ADDED]
if(dir.x >0 || dir.x <0 || dir.y >0 || dir.y <0)
{
isWalking = true;
}
else
{
isWalking = false;
}
}
void PlayerMove() // replace [dir] with [dirCurrent]
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -0.5f;
}
// [EDITED]
Vector3 moveDir = orientation.right * dirCurrent.x + orientation.forward * dirCurrent.y;
velocity.y += gravity * Time.deltaTime;
cc.Move(moveDir * moveSpeed * Time.deltaTime);
cc.Move(velocity * Time.deltaTime);
}
void CameraMove()
{
xRotation -= y;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
Quaternion targetRotation = Quaternion.Euler(xRotation, 0f, 0f); // [ADDED]
cam.localRotation = Quaternion.Lerp(cam.localRotation, targetRotation, Time.deltaTime * lookingSmoothTime); // [EDITED]
playerRotation *= Quaternion.Euler(Vector3.up * x); // [ADDED]
playerbody.rotation = Quaternion.Lerp(playerbody.rotation, playerRotation, Time.deltaTime * lookingSmoothTime); // [EDITED]
}
Add lines with comment: // [ADDED]
. Correct the lines with the comment: // [EDITED]
.
The smoothness can be changed by changing the variables lookingSmoothTime
and movingSmoothTime
in the Unity Editor.
Links:
Quaternion.Lerp; Mathf.Lerp; Vector3.Lerp.
Quaternion.RotateTowards; Mathf.MoveTowards; Vector3.MoveTowards.
Answer by Rokyloreq · Jun 20, 2021 at 12:39 PM
Thanks for your answer its more smooth but the player now slides if i release wasd
For an instant stop, you can use the conditions:
if (dir.x == 0) { dirCurrent.x = 0; }
if (dir.y == 0) { dirCurrent.y = 0; }
In MoveThePlayer()
right after the second Mathf.Lerp()
.
You can also stop smoothly:
if (dir.x == 0) { dirCurrent.x = Mathf.Lerp(dirCurrent.x, dir.x, Time.deltaTime * movingSmoothTime * 2); }
if (dir.y == 0) { dirCurrent.y = Mathf.Lerp(dirCurrent.y, dir.y, Time.deltaTime * movingSmoothTime * 2); }
(Write instead of conditions in the comment above).
Follow this Question
Related Questions
having CharacterController movement in fixedupdate causes jerky movement on camera 3 Answers
Trying to get camera to follow mouse, and player movement to be relative to camera angle? 0 Answers
Camera Modification Help 0 Answers
How to make an object go the direction it is facing? (Im new) 0 Answers
How to make an object go the direction it is facing? 0 Answers