- Home /
Object jitters when moving around it
As the title says, when I'm moving around the object I'm looking at, it jitters hard. However when I'm moving forward or strafe left, right, it looks normal. Edited: I edited the code so that all input logic is in Update and physics logic in FixedUpdate. Problem still remains.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] Rigidbody playerRigidbody;
[SerializeField] Transform playerTransform;
[SerializeField] Transform cameraTransform;
// Camera control variables
[SerializeField] float mouseSensitivity = 100f;
float xRotation = 0f; // xRotation is the rotation around x Axis, which is camera looking up down
float mouseX;
float mouseY;
// Movement control variables
[SerializeField] float movementSpeed = 12f;
Vector3 moveDirection;
float groundDragValue = 7f;
float movementSpeedMultiplier = 10f;
float forwardMovement;
float sideMovement;
// Jump control variable
[SerializeField] float jumpSpeed = 12f;
[SerializeField] Transform groundCheckSphere;
[SerializeField] LayerMask groundMask;
bool jumpInput;
bool isGrounded;
float airDragValue = 2f;
float airMovementSpeed = 5f;
// Crouch control variables
bool crouchInput;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
playerRigidbody.freezeRotation = true;
}
// Update is called once per frame
void Update()
{
MyInput();
}
// FixedUpdate has the frequency of Physic system and moving with ridigbody is based on Physic. So call MovementControl in
// FixedUpdate makes movement smoother.
private void FixedUpdate()
{
isGrounded = Physics.CheckSphere(groundCheckSphere.position, 0.4f, groundMask);
Debug.Log(isGrounded);
MovementControl();
JumpControl();
CameraControl();
DragControl();
CrouchControl();
}
void MyInput() {
// Get mouse input and apply mouse sensitivity
mouseX = Input.GetAxisRaw("Mouse X") * mouseSensitivity * Time.smoothDeltaTime;
mouseY = Input.GetAxisRaw("Mouse Y") * mouseSensitivity * Time.smoothDeltaTime;
// Get movement
forwardMovement = Input.GetAxisRaw("Vertical");
sideMovement = Input.GetAxisRaw("Horizontal");
// Get jump input
jumpInput = Input.GetKey(KeyCode.Space);
// Get crouch input
crouchInput = Input.GetKey(KeyCode.LeftControl);
}
void CameraControl()
{
// Look horizontal
playerTransform.Rotate(0f, mouseX, 0f, Space.Self);
// Look vertical
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
cameraTransform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
}
void MovementControl()
{
moveDirection = transform.forward * forwardMovement + transform.right * sideMovement;
// Use normalized to make all the magnitudes to [-1, 1]
if (isGrounded)
{
playerRigidbody.AddForce(moveDirection.normalized * movementSpeed * movementSpeedMultiplier, ForceMode.Acceleration);
} else
{
playerRigidbody.AddForce(moveDirection.normalized * airMovementSpeed * movementSpeedMultiplier, ForceMode.Acceleration);
}
}
void DragControl()
{
if (isGrounded)
{
playerRigidbody.drag = groundDragValue;
} else
{
playerRigidbody.drag = airDragValue;
}
}
void CrouchControl()
{
if (crouchInput)
{
playerTransform.localScale = new Vector3(playerTransform.localScale.x, 1.3f, playerTransform.localScale.z);
} else
{
playerTransform.localScale = new Vector3(playerTransform.localScale.x, 2f, playerTransform.localScale.z);
}
}
void JumpControl()
{
if (jumpInput && isGrounded)
{
playerRigidbody.AddForce(transform.up * jumpSpeed, ForceMode.Impulse);
}
if (playerRigidbody.velocity.y < 0)
{
playerRigidbody.AddForce(Physics.gravity * 4, ForceMode.Acceleration);
}
}
}
Here's the video to show https://www.youtube.com/watch?v=NUFIuGwpm-M
Perhaps add your "CameraControll()" to update/fixedupdate instead of late update? (Just to see what difference that makes)
Yes I did but the problem still remains :(
Answer by andrew-lukasik · Apr 19, 2021 at 11:36 AM
It's because you're rotating a camera transform in
FixedUpdate
with zero relation to delta time between calls. This leads to inconsistent rotation as rendering frequency (framerate) is decoupled from physics updates.
It turned out that at least few factors contributed to this camera jitter behaviour. One, probably major one, was RB Interpolation
setting while Camera being parented to that RB.
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] Rigidbody playerRigidbody;
[SerializeField] Transform playerTransform;
[SerializeField] Transform cameraTransform;
// Camera control variables
[SerializeField] float mouseSensitivity = 100f;
float _xRotation = 0f; // xRotation is the rotation around x Axis, which is camera looking up down
float _mouseX, _mouseY;
// Movement control variables
[SerializeField] float movementSpeed = 12f;
float groundDragValue = 7f;
float movementSpeedMultiplier = 10f;
float _forwardMovement, _sideMovement;
// Jump control variable
[SerializeField] float jumpSpeed = 12f;
[SerializeField] Transform groundCheckSphere;
[SerializeField] LayerMask groundMask = 1<<0;
bool _jumpInput, _isGrounded;
float _airDragValue = 2f;
float _airMovementSpeed = 5f;
// Crouch control variables
bool _crouchInput;
[SerializeField][Min(0.001f)] float _mouseInputInterpolationTime = 0.1f;
void Start ()
{
Cursor.lockState = CursorLockMode.Locked;
playerRigidbody.freezeRotation = true;
}
void Update ()
{
float deltaTime = Time.deltaTime;
// read player inputs:
_mouseX = Mathf.Lerp( _mouseX , Input.GetAxis("Mouse X") * mouseSensitivity , deltaTime*(1f/_mouseInputInterpolationTime) );
_mouseY = Mathf.Lerp( _mouseY , Input.GetAxis("Mouse Y") * mouseSensitivity , deltaTime*(1f/_mouseInputInterpolationTime) );
_forwardMovement = Input.GetAxisRaw("Vertical");
_sideMovement = Input.GetAxisRaw("Horizontal");
_jumpInput = Input.GetKey(KeyCode.Space);
_crouchInput = Input.GetKey(KeyCode.LeftControl);
}
void FixedUpdate ()
{
float deltaTime = Time.fixedDeltaTime;
_isGrounded = Physics.CheckSphere( groundCheckSphere.position , 0.4f , groundMask );
// MovementControl();
var moveDirection = Vector3.Normalize( transform.forward*_forwardMovement + transform.right*_sideMovement );
var moveSpeed = _isGrounded ? movementSpeed : _airMovementSpeed;
playerRigidbody.AddForce( moveDirection * moveSpeed * movementSpeedMultiplier , ForceMode.Acceleration );
// JumpControl();
if( playerRigidbody.velocity.y<0 ) playerRigidbody.AddForce( Physics.gravity * 4 , ForceMode.Acceleration );
else if( _jumpInput && _isGrounded ) playerRigidbody.AddForce( Vector3.up * jumpSpeed , ForceMode.Impulse );
// DragControl();
playerRigidbody.drag = _isGrounded ? groundDragValue : _airDragValue;
// CrouchControl();
float crouchScale = _crouchInput ? 1.3f : 2f;
playerTransform.localScale = new Vector3( playerTransform.localScale.x , crouchScale , playerTransform.localScale.z );
// CameraControl();
// mouse look, horizontal
playerTransform.Rotate( 0 , _mouseX*deltaTime , 0 );
// mouse look, vertical
_xRotation = Mathf.Clamp( _xRotation - _mouseY*deltaTime , -90f , 90f );
cameraTransform.localRotation = Quaternion.Euler( _xRotation , 0f , 0f );
}
}
The mouseY variable has relation to the Time.deltatime. Or do you mean that when using Mathf.Clamp the relation doesn't work anymore?
Yeah, no. You're multiplying those values in Update
by Time.smoothDeltaTime
so that makes them related to frame rendering time, not physics step time. Call CameraControl
in Update
at least.
I tried to put CameraControl in Update, but it does not solve the problem. I tried to multiply the Time.smoothDeltaTime in the CameraControl and put it in FixedUpdate so that it can be related to physics time step. It does reduce the jitter a bit. however it does not also solve the problem . The jittering still remains.
@tongvietdung I edited my answer above and added actual code. Try it and please report did it help or not.
Unfortunately it did not. The camera movement is smoother however xD.
It's smooth as silk on my machine. I have no idea how to reproduce your case then. Does your setup looks the same as $$anonymous$$e?
Answer by Lifes_great · Apr 19, 2021 at 12:18 AM
The problem isn't to do with the object but it's todo with your camera. All you need todo is is replace Time.DeltaTime with Time.smoothDeltaTime
Hopefully this works :D.
Unfortunately, replacing Time.DeltaTime with Time.smoothDeltaTime does not work for me.
Guys, don't be seduced by that "smooth" word there. Good sounding words are nice, but numbers is what really counts here.
Also it's important to understand what Time.deltaTime
is for exactly (numerically). Because immediately you will see that Time.smoothDeltaTime
is mostly useless or even detrimental.
// sensible use case:
Debug.Log($"Framerate: {(int)(1f/Time.smoothDeltaTime)}");
// but not this:
Vector3 step = direction * speed * Time.smoothDeltaTime;// < this is wrong
Answer by Kaldrin · Apr 19, 2021 at 10:20 AM
The ground is not jittering though right? This is very strange The object has no custom behaviour, it's just a box?
Yes the ground is not jittering. And the box is just a default Cube 3D object.
Answer by tongvietdung · Apr 19, 2021 at 12:45 PM
So as andrew-lukasisk (sorry I cannot tag you some how) explained above, I tried to move the multiplication withTime.smoothDeltaTime into the CameraControl method. Therefore it will be called in FixedUpdate to match the camera movement with the physics update. However it does not solve the problem at first.
BUT I tried increasing the frequency of FixedUpdate call by changing the Fixed Timestep from 0.02 to about 0.0025. And it reduces the jittering (but still can be noticable). And changing it to 0.001, the jittering reduces to the point I think acceptable. But if one put attention on it, the jittering can still be notice.
I'm fairly new with this technical thingy, therefore I don't know what is the downside of the small Fixed Timestep. So if there is other solution, please share.
I think it's mostly for performance issues, running the fixed update that many times per frame can be quite consu$$anonymous$$g, but I'm not sure.
One thing I could suggest is to put other meshes and see how it behaves when you look at them too, and maybe make a custom command to slow down time (Set the timescale) and see what happens then, it might help you pinpoint the issues
@tongvietdung Change Fixed Timestep back to it's original value. It's neither sustainable nor reasonable solution to problem at hand.
Your answer
Follow this Question
Related Questions
How to make FPS Camera bounce when walking 1 Answer
WebGl Mouse Look Problem 0 Answers
localRotation rotates by 180° 1 Answer
Im trying to lerp a rotation when I press a key. 0 Answers
how do i disable fps controler 0 Answers