Free Look camera stuttering when following a moving object. how to fix ?

The free look camera settings: Definition -Target Forward and Binding Mode - World Space.
I tried to change the Binding Mode to Simple Follow With World Up but it didn’t change much.

The camera is following and looking at the player and the player is child of a platform. the platform object has a script that making the platform object move between waypoints.

if the platform moving script is turned off and the platform is not moving everything is working fine.
but if the platform is moving the camera is stuttering.

this is the script that is attached to the Platform object and make it moving:
I tried to change it from Update to FixedUpdate and LateUpdate but othing helped.
The character have a Rigidbody and Animator with animations and the default animation is idle.

using UnityEngine;

public class MoveOnCurvedLines : MonoBehaviour
{
    public LineRenderer lineRenderer;
    public float speed;
    public bool go = false;
    public bool moveToFirstPositionOnStart = false;
    public Transform player;
    public bool rotatePlayerLookAtDirection = false;

    private Vector3[] positions;
    private Vector3[] pos;
    private int index = 0;
    private bool goForward = true;

    // Start is called before the first frame update
    void Start()
    {
        pos = GetLinePointsInWorldSpace();

        if (moveToFirstPositionOnStart && pos.Length > 1)
        {
            transform.position = pos[index];
            // Rotate the player to look at the direction of the next waypoint if not already looking at it
            if (rotatePlayerLookAtDirection)
            {
                Vector3 directionToNextPoint = pos[index + 1] - pos[index];
                if (player != null && player.forward != directionToNextPoint.normalized)
                {
                    player.rotation = Quaternion.LookRotation(directionToNextPoint);
                }
            }
        }
    }

    Vector3[] GetLinePointsInWorldSpace()
    {
        positions = new Vector3[lineRenderer.positionCount];
        // Get the positions which are shown in the inspector 
        lineRenderer.GetPositions(positions);

        // The points returned are in world space
        return positions;
    }

    // Update is called once per frame
    private void Update()
    {
        if (go)
        {
            if (rotatePlayerLookAtDirection)
            {
                Vector3 directionToNextPoint = pos[index + 1] - pos[index];
                if (player != null && player.forward != directionToNextPoint.normalized)
                {
                    //player.rotation = Quaternion.LookRotation(directionToNextPoint);
                }
            }

            Move();
        }
    }

    void Move()
    {
        Vector3 newPos = transform.position;
        float distanceToTravel = speed * Time.deltaTime;

        bool stillTraveling = true;
        while (stillTraveling)
        {
            Vector3 oldPos = newPos;
            newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);
            distanceToTravel -= Vector3.Distance(newPos, oldPos);
            if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
            {
                // When you hit a waypoint:
                if (goForward)
                {
                    bool atLastOne = index >= pos.Length - 1;
                    if (!atLastOne) index++;
                    else { index--; goForward = false; }
                }
                else
                { // Going backwards:
                    bool atFirstOne = index <= 0;
                    if (!atFirstOne) index--;
                    else { index++; goForward = true; }
                }
            }
            else
            {
                stillTraveling = false;
            }
        }

        transform.position = newPos;
    }
}

and the player the character has a script attached that make it look at smooth a target:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmoothLookAt : MonoBehaviour
{
    public Transform target;
    public float lookSpeed = 5f; // Control the speed of the rotation

    void Update()
    {
        // Determine the target rotation. This is the rotation where the gameObject looks at the target
        Quaternion targetRotation = Quaternion.LookRotation(target.position - transform.position);

        // Smoothly rotate towards the target point.
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, lookSpeed * Time.deltaTime);
    }
}

Again! if the platform is not moving everything is working fine. the camera is in close range on the character that smoothly look at a target. but if the platform is moving then the camera is stuttering.

and i want that the player will look smooth at the target the same way if the platform is not moving also from close range smooth look at.

this screenshot showing the Platform structure objects and children. and the camera settings in the inspector:

  1. Unparent your FreeLook from the main camera. One should not be a child of the other, ever.
  2. How are you moving the player? Does it have a Rigidbody?
1 Like

unparent. and about the player.

The player have a Rigidbody.
here is a screenshot of the player inspector settings:

So the problem is very likely due to a mismatch between movement methods. Player is moving on FixedUpdate but platform is moving on Update. You need to make sure that all targets being tracked by Cinemachine cameras are moving on the same clock, and then when Cinemachine updates on that clock, it will be smooth.

The best solution would be to enable Interpolation on your player’s rigidbody. That will convert its motion into Update-compatible motion. However, you need to be moving the rigidbody properly for interpolation to work. I don’t know what your character scripts are doing.

To test, put the CM Brain in SmartUpdate, turn on rigidbody interpolation for the player, and play the game. When the game is playing (don’t go on the platform yet), look at the vcam inspector. Next to the Solo button, it will tell you how it is tracking the player. It will say Late Update or Fixed Update. What does it say? Is the motion smooth?

1 Like

it’s still stuttering. the brain was already on smart update and in the player i changed the interpolate to interpolate it was none.

in the camera near the solo it says Late Update and i tried to change in the brain to all the update types in the update method but nothing fixed it yet.

I will upload a short video clip showing the whole project in the editor and the problem and the settings of everything.

Instead of a video, can you send me a small project that shows this problem? It will be easier to diagnose that way.

1 Like

here is a link to download the project. the project size is about 200 MB :

i noticed two problems in my project:

  1. when the script moving platform that is attached to the gameobject platform if the variable go in the inspector is checked true then when running the game the object SciFi_Space_Drone_A is falling down under the platform floor.

  2. second problem when the go variable in the moving platform script is checked true is the stuttering camera.

I forgot to mention what am i trying to do.

a cut scene.

I want that when the game start there is close shot camera on the player and the player is smooth looking at the drone and then after few seconds with cameras transition the drone is smooth making his way and stand forward looking at the player and there is a conversation between the drone and the player.

and all this cut scene while the platform is moving.

The link is gone. Can you re-post? You can DM it to me if you like.