Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Network transform jittering on client side with FixedUpdate and Cinemachine FixedUpdate

Discussion in 'Multiplayer' started by sofabivaadin, Jun 6, 2023.

  1. sofabivaadin

    sofabivaadin

    Joined:
    Apr 7, 2022
    Posts:
    5
    Hi, I am creating a multiplayer platformer, and i use Mirror for the networking and Unity 2020.3.48

    I just want for example to move a cube and sync is position to all clients.

    I use FixedUpdate() to move player and also to move the cube.
    My cube have just a script with a basic Network transform, the movement is driving by server. (No client authority).

    But when i move the player on client side i see the cube jittering ? On server side / host side no jittering. I really don't understand why ?

    I recreate a minimalist project for testing this issue.

    My Code for moving the cube :
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Mirror;
    5.  
    6. public class TestMoveNetwork : NetworkBehaviour
    7. {
    8.  
    9.     public float TimeBeforeGoToOtherDirection;
    10.     public float TimePassed;
    11.  
    12.     public Vector3 direction;
    13.  
    14.     public Rigidbody rb;
    15.  
    16.     private void Awake() {
    17.         this.rb = GetComponent<Rigidbody>();
    18.     }
    19.  
    20.     void Start() {
    21.  
    22.         direction = Vector3.left;
    23.  
    24.         TimeBeforeGoToOtherDirection = 3f;
    25.         TimePassed = 0f;
    26.     }
    27.  
    28.     void Update() {
    29.  
    30.     }
    31.  
    32.     private void FixedUpdate() {
    33.  
    34.         if(isServer) {
    35.             simpleMove();
    36.             //simpleMoveRigidbody();
    37.         }
    38.     }
    39.  
    40.     private void simpleMove() {
    41.  
    42.         float speed = 6f;
    43.  
    44.         TimePassed += Time.deltaTime;
    45.         if(TimePassed >= this.TimeBeforeGoToOtherDirection) {
    46.  
    47.             TimePassed = 0f;
    48.  
    49.             direction = -direction;
    50.         }
    51.  
    52.         Debug.Log(Time.deltaTime);
    53.         Debug.Log(Time.fixedDeltaTime);
    54.  
    55.         transform.Translate(direction * Time.fixedDeltaTime * speed);
    56.     }
    57.  
    58.     private void simpleMoveRigidbody() {
    59.  
    60.         float speed = 150f;
    61.  
    62.         TimePassed += Time.deltaTime;
    63.         if(TimePassed >= this.TimeBeforeGoToOtherDirection) {
    64.  
    65.             TimePassed = 0f;
    66.  
    67.             direction = -direction;
    68.             this.rb.velocity = Vector3.zero;
    69.             this.rb.AddForce(direction * speed);
    70.         }
    71.     }
    72. }
    My code for moving the player :
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Mirror;
    5. using Cinemachine;
    6.  
    7. [RequireComponent(typeof(CapsuleCollider))]
    8. [RequireComponent(typeof(CharacterController))]
    9. [RequireComponent(typeof(NetworkTransform))]
    10. [RequireComponent(typeof(Rigidbody))]
    11. public class PlayerControllerTest : NetworkBehaviour
    12. {
    13.     public CharacterController characterController;
    14.  
    15.     //public Camera OldMainCamera;
    16.  
    17.     [Header("Movement Settings")]
    18.     public float moveSpeed = 8f;
    19.     public float turnSensitivity = 5f;
    20.     public float maxTurnSpeed = 100f;
    21.  
    22.     [Header("Diagnostics")]
    23.     public float horizontal;
    24.     public float vertical;
    25.     public float turn;
    26.     public float jumpSpeed;
    27.     public bool isGrounded = true;
    28.     public bool isFalling;
    29.     public Vector3 velocity;
    30.  
    31.     void OnValidate()
    32.     {
    33.         if (characterController == null)
    34.             characterController = GetComponent<CharacterController>();
    35.  
    36.         characterController.enabled = false;
    37.         GetComponent<Rigidbody>().isKinematic = true;
    38.         GetComponent<NetworkTransform>().clientAuthority = true;
    39.         //OldMainCamera.enabled = false;
    40.     }
    41.  
    42.     public override void OnStartLocalPlayer()
    43.     {
    44.         characterController.enabled = true;
    45.         //OldMainCamera.enabled = true;
    46.         GameManager._gameManagerInstance.thirdPersonVirtualCamera.GetComponent<CinemachineVirtualCamera>().Follow = this.transform;
    47.     }
    48.  
    49.     void Update()
    50.     {
    51.         if (!isLocalPlayer || characterController == null || !characterController.enabled)
    52.             return;
    53.  
    54.         horizontal = Input.GetAxis("Horizontal");
    55.         vertical = Input.GetAxis("Vertical");
    56.  
    57.         // Q and E cancel each other out, reducing the turn to zero
    58.         if (Input.GetKey(KeyCode.A))
    59.             turn = Mathf.MoveTowards(turn, -maxTurnSpeed, turnSensitivity);
    60.         if (Input.GetKey(KeyCode.E))
    61.             turn = Mathf.MoveTowards(turn, maxTurnSpeed, turnSensitivity);
    62.         if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.E))
    63.             turn = Mathf.MoveTowards(turn, 0, turnSensitivity);
    64.         if (!Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.E))
    65.             turn = Mathf.MoveTowards(turn, 0, turnSensitivity);
    66.  
    67.         if (isGrounded)
    68.             isFalling = false;
    69.  
    70.         if ((isGrounded || !isFalling) && jumpSpeed < 1f && Input.GetKey(KeyCode.Space))
    71.         {
    72.             jumpSpeed = Mathf.Lerp(jumpSpeed, 1f, 0.5f);
    73.         }
    74.         else if (!isGrounded)
    75.         {
    76.             isFalling = true;
    77.             jumpSpeed = 0;
    78.         }
    79.     }
    80.  
    81.     void FixedUpdate()
    82.     {
    83.         if (!isLocalPlayer || characterController == null || !characterController.enabled)
    84.             return;
    85.  
    86.         transform.Rotate(0f, turn * Time.fixedDeltaTime, 0f);
    87.  
    88.         Vector3 direction = new Vector3(horizontal, jumpSpeed, vertical);
    89.         direction = Vector3.ClampMagnitude(direction, 1f);
    90.         direction = transform.TransformDirection(direction);
    91.         direction *= moveSpeed;
    92.  
    93.         if (jumpSpeed > 0)
    94.             characterController.Move(direction * Time.fixedDeltaTime);
    95.         else
    96.             characterController.SimpleMove(direction);
    97.  
    98.         isGrounded = characterController.isGrounded;
    99.         velocity = characterController.velocity;
    100.     }
    101. }
    102.  

    My scene (Host Side)


    NetworkTransform on Cube :


    NetworkTransform on Player :


    The cinemachine brain update mode and blend mode are on FixedUpdate()
    Cinemachine virtual Camera use body 3rd person follow with on follow player transform :


    The jittering on client (For this one i try this last version of Mirror) :

     
    Last edited: Jun 9, 2023