Hello, I have made a script, by using the CharacterController component, to control a first person character.
I used the scripts found in Unity’s API, and added some rotation lines in order to rotate the camera and the character itself.
I made a game object in the scene, attached the CharacterController component and the script to it. Then, I parented a camera to it, which functions as the “head”.
It works.
But…
The camera feels very stuttery when moving it. I tried changing the lines around, putting them in LateUpdate and FixedUpdate, even un-parenting the camera from the character object, as I heard that might be making things weird.
But no matter what I do, there always seems to be a level of stutter.
I imported Unity’s own FPSController, to check if maybe the scene was laggy, but that wasn’t the case. The FPSController’s camera was very smooth.
What am I doing wrong, and is there a way I could fix that somehow?
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour {
[Header("Player Controls")]
public float speed = 4f;
public float runSpeed = 4f;
public float crouchSpeed = 1.5f;
public float jumpSpeed = 5.0f;
public float gravity = 25.0f;
private Vector3 moveDirection = Vector3.zero;
public bool running = false;
public bool crouching = false;
[Header("Rotation Controls")]
public float rotateX;
public float rotateY;
public float rotationSpeed = 80f;
private Camera playerCam;
void Start()
{
playerCam = GetComponentInChildren<Camera>();
}
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded)
{
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
if (running)
moveDirection *= runSpeed;
if (crouching)
moveDirection *= crouchSpeed;
else
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
if (Input.GetKey(KeyCode.LeftControl) && !running)
{
crouching = true;
}
else
crouching = false;
}
if (Input.GetKey(KeyCode.LeftShift) && !running)
{
running = true;
}
else
running = false;
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
rotateX -= (Input.GetAxis("Mouse Y")) * rotationSpeed * Time.deltaTime;
rotateY += (Input.GetAxis("Mouse X")) * rotationSpeed * Time.deltaTime;
transform.rotation = Quaternion.Euler(new Vector3(0, rotateY, 0));
}
void LateUpdate()
{
playerCam.transform.localRotation = Quaternion.Euler(new Vector3(rotateX, 0, 0));
}
}
I don’t know why you are getting Jitter, but here are some things to consider:
There may be genuinely large / irregular gaps between frames. These can be picked up quite easily by the eye. Maybe monitor frame-rate and output a debug message if it drops below 60 / 30 FPS. Could something in your game sometimes be holding the CPU for too long causing uneven frame rate drops?
Could something else be updating / overwriting the camera position? If two different places in the code are fighting to control the camera that could also cause jittering.
I know you have not done this in your code above, but just to mention - don’t mix using Time.deltaTime with FixedUpdate(). They are naturally opposed; FixedUpdate() is deliberately consistent in its time intervals.
Also, it is generally recommended to avoid getting into the habit of calling GetComponent() within Update(). Rather, move line 32 into Start() - obviously you will need to create a new member variable to store the component reference.
Camera jitters a lot of the time have to do with order of operations. Moving and rotating the player, and the camera, in different updates or on the wrong order is most often the cause of jitters that aren’t frame rate related. For a first person camera don’t rotate the character at all, keep it orientation static, and move it in the direction of the camera transforms right and flattened forward vector. Then a parented camera should follow smoothly, and the camera just rotates. I believe your jitters are caused by your rotating the player controller in update and then modifying the local rotation of the camera in late update. I’m not at home to play with the code though
Hi, thank you for your replies. I have to say, I don’t know what it was that day. Maybe some kinda Unity hiccup, because after a day, when I turned my project back on, the camera seems to be perfectly smooth now.
I just hope it was a one-time thing.
Either way, though, I thank you for your suggestions and additional info. I will definitely keep all of it in mind.
I’m a little late to the party here, but I feel like saying that the editor isn’t the best place to play your game. If that’s where you are experiencing the jitters, try making a build and play the game on its own and see what happens.
Hi! I know this is a very late reply, but I’d like to say that your clarification helped me a lot here! I updated my player movement and put it in a FixedUpdate as opposed to the regular Update function. I realized the jitters only happened when I added a rigidbody, so it was obvious why the FixedUpdate would be a muchhh better place lol