Search Unity

Resolved How To Sync Transform and Physics without the use of ClientNetworkTransform.

Discussion in 'Netcode for GameObjects' started by babaliaris, Jan 26, 2024.

  1. babaliaris

    babaliaris

    Joined:
    Apr 21, 2013
    Posts:
    40
    Hello.

    I'm playing with the Netcode for objects in Unity and every single tutorial out there tells you that you are not supposed to trust the client, and they continue the tutorial using the ClientNetworkTransform component without telling you how to achieve the same goal without it.

    I read in the docs about the NetworkTransform and the NetworkRigidbody, but I can not figure out how to make a simple 2-player spawn with working movement and physics. The client just stucks in the air without moving at all.

    Also trying to move the client by asking the server using a ServerRpc, does not work. The Rpc is called successfully in the server with the x,y data given by the client, but the ServerRpc method seems not to update the script variables at all:

    Code (CSharp):
    1. using Unity.Netcode;
    2. using UnityEngine;
    3. using UnityEngine.InputSystem;
    4.  
    5. public class PlayerMovementScript : NetworkBehaviour
    6. {
    7.  
    8.     [SerializeField] private float MoveSpeed = 100;
    9.  
    10.     private Vector2 mMoveInput;
    11.     private Rigidbody mRigidbodyRef;
    12.  
    13.  
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         mRigidbodyRef = GetComponent<Rigidbody>();
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.     }
    24.  
    25.     void FixedUpdate()
    26.     {
    27.         if (mMoveInput != Vector2.zero)
    28.         {
    29.             mRigidbodyRef.AddForce( (transform.right * mMoveInput.x + transform.forward * mMoveInput.y) * Time.deltaTime * MoveSpeed );
    30.             Debug.Log("Force ("+mMoveInput.x+" , "+mMoveInput.y+") " + "Applied to: " + OwnerClientId);
    31.         }
    32.     }
    33.  
    34.  
    35.     public void OnMove(InputAction.CallbackContext ctx)
    36.     {
    37.         Vector2 input = ctx.ReadValue<Vector2>();
    38.  
    39.         MoveServerRpc(input.x, input.y);
    40.     }
    41.  
    42.  
    43.     [ServerRpc]
    44.     private void MoveServerRpc(float x, float y)
    45.     {
    46.         mMoveInput.x = x;
    47.         mMoveInput.y = y;
    48.         Debug.Log("Move ("+x+" , "+y+") " + "Request By: " + OwnerClientId);
    49.     }
    50. }
    The client who is also the host, calling the Rpc results in a successful update of mMoveInput.x & mMoveInput.x and the object moves around in both the host and the client.

    When another connected client calls the MoveServerRpc, the Rpc method is indeed called on the server but it seems like the mMoveInput.x & mMoveInput.x do not update at all, but remain zero, causing the code inside the FixedUpdate() to not run. So the object does not move either on the server or the client.

    Even if I make this work, the physics will still not work properly. The client will fall due to gravity on the server but on the client's screen, it gets stuck in the air.

    What is the purpose of NetworkTransform and NetworkRigidbody then if they don't work
    out of the box? Why can't they just sync the client's data using the physics run on the server?
    Since the client player objects spawn and fall on the server, why does it get stuck on the client?
    Shouldn't the NetworkTransform and NetworkRigidbody automatically say "Oh the player instantiated object is falling on the server, so let's broadcast that to all the clients so the object will fall on the clients as well." This seems logical to me.
    It seems like by default, on the client side the instantiated object tries to fall using the physics run on that computer, and this is why it stucks. It seems weird to me why it does not update by default to the state of the servers physics.



    So how do you make this work properly?
    By properly I mean the right way Unity intends you to follow, not using the ClientNetworkTransform that is going against the security policy.
     
    Last edited: Jan 26, 2024
  2. babaliaris

    babaliaris

    Joined:
    Apr 21, 2013
    Posts:
    40
    I still have a problem with the rigid body network transform, but the rest was my fault. I was disabling the script that was responsible for handling the ServerRpc and applying the force to the NetworkObject, this is why the force was not moving the object. I will make another post if I'm still stuck with the Kinematic Object on the client side. Probably I will have to copy the server object and use it as a puppet to control the kinematic Rigidbody on the client.