Search Unity

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:
    6
    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