Agents jitter because camera FixedUpdate

Hello everyone,

I tried all possible configurations, but either the player jitter or the camera(What only causes this on the Agents).
If I switch camera in LateUpdate, Agents work well, BUT, something I do not understand! When I shoot at them with projectiles and I’m in motion, the player remakes jiterring -_-’

The 3 scripts:
Player

        if (IsMove == true) {
            if (SaveLoadDeleteScript.Keyboard == 0) {
                float h = Input.GetAxisRaw ("Horizontal");
                float v = Input.GetAxisRaw ("Vertical");

                Movement.Set (h, 0f, v);

                if (IsConveyorBelt == false) {
                    Movement = Movement.normalized * SaveLoadDeleteScript.MovementSpeed * Time.deltaTime;
                } else if (IsConveyorBelt == true) {
                    ConveyorBeltSpeed = SaveLoadDeleteScript.MovementSpeed / 2;
                    Movement = Movement.normalized * ConveyorBeltSpeed * Time.deltaTime;
                }

                playerRigidbody.MovePosition (transform.position + Movement);

                if (SaveLoadDeleteScript.Keyboard == 0) {
                    if (Movement != new Vector3 (0, 0, 0)) {
                        TimerUntilPlayerFirstMovement = 1;
                        TimerUntilPlayerFirstMovementSpeed = 5;
                        if ((Input.GetKeyDown (KeyCode.Space)) && (IsDashReady == false) && (IsOppositeInput0_1 == false) && (IsOppositeInput0_2 == false)) {
                            Dash();
                            PlayerDashSFX.Play ();
                        }
                    }
                } else if (SaveLoadDeleteScript.Keyboard == 1) {
                    if (Movement != new Vector3 (0, 0, 0)) {
                        TimerUntilPlayerFirstMovement = 1;
                        TimerUntilPlayerFirstMovementSpeed = 5;
                        if ((Input.GetKeyDown (KeyCode.Space)) && (IsDashReady == false) && (IsOppositeInput1_1 == false) && (IsOppositeInput1_2 == false)) {
                            Dash();
                            PlayerDashSFX.Play ();
                        }
                    }
                }
                if ((PlayerFirstMovement == false) && (Movement != new Vector3 (0, 0, 0))) {
                    PlayerFirstMovement = true;
                    PlayerFirstMovementSFX.Play ();
                }
            }

Camera

/*-----------------------------------------------------*/
    void Start () {
        Offset = new Vector3 (transform.position.x - Target.position.x, 45, transform.position.z - Target.position.z);
        Offset2 = new Vector3 (transform.position.x - Target.position.x, 90, transform.position.z - 36.8f - Target.position.z);
    }
/*-----------------------------------------------------*/
    void FixedUpdate () {
        if (IsZoomOut == true) {
            Vector3 TargetCamPos = Target.position + Offset;
            transform.position = Vector3.Lerp (transform.position, TargetCamPos, Smoothing * Time.deltaTime);
            if (Scan == false) {
                Scan = true;
                this.GetComponent<CameraFilterPack_3D_Scan_Scene> ().enabled = false;
                this.GetComponent<CameraFilterPack_3D_Scan_Scene> ()._Distance = 0;
            }
        }
        if (IsZoomOut == false) {
            Vector3 TargetCamPos = Target.position + Offset2;
            transform.position = Vector3.Lerp (transform.position, TargetCamPos, Smoothing * Time.deltaTime);
            this.GetComponent<CameraFilterPack_3D_Scan_Scene> ().enabled = true;
        }
    }

Agents

    void Update () {
        if (PlayerLifeScript.IsDead == false) {
            if (IsFollow == true) {
                Agent.enabled = true;
                Agent.SetDestination (Player.position);
            }
        }
    }

Thanks guys

Alexandre

There are a couple of things I noticed:

  • You didn’t show us what function that code is in for the Player snippet. Update? FixedUpdate?
  • In FixedUpdate you should use Time.fixedDeltaTime as opposed to Time.deltaTime otherwise the timing will be wrong.
  • Why do you not cache CameraFilterPack_3D_Scan_Scene in your camera script? While not directly related to the issue it would make the code cleaner and probably easier to read which is definitely a bonus.
  1. Player script “Update”
  2. Yes but switch in Time.fixedDeltaTime don’t change anything.
  3. And Yes CameraFilterPack is not important in the script.

Enable interpolation on rigidbodies. Put cam code in LateUpdate.

Putting camera code inside fixedupdate is useless, don’t do it. Fixed update doesn’t compensate for varying frametimes nor run at the same rate as the main loop.

1 Like

I show you again with modification the different scripts, but with that config another problem appears.

Player

    void Update () {
        if (IsMove == true) {
            if (SaveLoadDeleteScript.Keyboard == 0) {
                float h = Input.GetAxisRaw ("Horizontal");
                float v = Input.GetAxisRaw ("Vertical");

                Move (h, v);
            } else if (SaveLoadDeleteScript.Keyboard == 1) {
                float h = Input.GetAxisRaw ("HorizontalAZERTY");
                float v = Input.GetAxisRaw ("VerticalAZERTY");

                Move (h, v);
            }
            Turning ();
        }
    }
    void Move (float h, float v)
    {
        Movement.Set (h, 0f, v);

        Movement = Movement.normalized * SaveLoadDeleteScript.MovementSpeed * Time.deltaTime;

        playerRigidbody.MovePosition (transform.position + Movement);
    }

Camera

    void LateUpdate () {
        if (IsZoomOut == true) {
            Vector3 TargetCamPos = Target.position + Offset;
            transform.position = Vector3.Lerp (transform.position, TargetCamPos, Smoothing * Time.deltaTime);
        }
        if (IsZoomOut == false) {
            Vector3 TargetCamPos = Target.position + Offset2;
            transform.position = Vector3.Lerp (transform.position, TargetCamPos, Smoothing * Time.deltaTime);
        }
    }

Agents

    void Update () {
        if (PlayerLifeScript.IsDead == false) {
            if (IsFollow == true) {
                Agent.enabled = true;
                Agent.SetDestination (Player.position);
            }
        }
    }

Player Rigidbody (screenshot).

I shoot with my main character while moving. If the shot (Rigidbody, move translate) hits an enemi (rigidbody, move nav) and the character is still moving, it makes a tremor / jitter on the character.

Why does my character (who has to be moving, otherwise all right) tremor / jitter when 2 rigidbody comes into contact? He is not concerned…

I disabled the camera movement, the problem persists on the character.

sorry about my rough English and thanks for your help, I really hope you find the solution.

Alexandre

4387558--398440--Capture.PNG

You have…
4388281--398530--upload_2019-4-3_14-29-48.png

I said…

Put Interpolate.
4388281--398533--upload_2019-4-3_14-32-24.png
https://docs.unity3d.com/Manual/class-Rigidbody.html

Because physics have less steps than main loop. It is a fixed update where physics are updated, but the in-between frames are calculated with Interpolate! :slight_smile:

There is no interpolate feature for camera, so we put that in LateUpdate and do regular smoothing in there with lerp or smoothdamp (smoothdamp automatically calculates delta time).

Yes sorry Hippocoder BUT I did your method before but it does not work. So I put in NONE again…
The problem is still here.

Can’t help you, what I described is the correct process. Perhaps you’re not moving the Rigidbody correctly using .MovePositon or velocity? (transform position inside fixed update will NOT interpolate - this is a teleport and will stutter).

So if you perform .MovePosition in Update it will probably not work like you think it will.

The player have a rigidbody and move with that:

        void Update () {
            if (IsMove == true) {
                if (SaveLoadDeleteScript.Keyboard == 0) {
                    float h = Input.GetAxisRaw ("Horizontal");
                    float v = Input.GetAxisRaw ("Vertical");
    
                    Move (h, v);
                } else if (SaveLoadDeleteScript.Keyboard == 1) {
                    float h = Input.GetAxisRaw ("HorizontalAZERTY");
                    float v = Input.GetAxisRaw ("VerticalAZERTY");
    
                    Move (h, v);
                }
                Turning ();
            }
        }
        void Move (float h, float v)
        {
            Movement.Set (h, 0f, v);
    
            Movement = Movement.normalized * SaveLoadDeleteScript.MovementSpeed * Time.deltaTime;
    
            playerRigidbody.MovePosition (transform.position + Movement);
        }

But that problem appears when (look the step below):

  1. The player move and shoot
  2. The projectile (rigidbody) hit an enemy (rigidbody)
  3. The player tremor / jitter

You are moving it in Update though… so interpolate won’t function. Read manual. What MovePosition really does is calculate a velocity for the rigidbody and apply it in the next FIXED update.

What you should do is only move rigidbodies inside fixedupdate. I keep saying it but you’re not listening.

FixedUpdate exists only for physics movement.

1 Like

Thank you hippocoder! You are the best. Everything is working now.
Sorry for my misunderstanding.

1 Like