Search Unity

How I can make the server move a client object?

Discussion in 'Multiplayer' started by livegamezde, Oct 20, 2022.

  1. livegamezde

    livegamezde

    Joined:
    Sep 6, 2021
    Posts:
    3
    Hey guys,

    this might be a silly question but I'm going insane over this issue:
    So I have a very simple project with client sided movement and server sided raycast shooting.
    After getting killed (networkvariable<int> health <=0) the player is supposed to teleport to a random position.
    When the client kills the host, everything is fine, but when the host kills the client, the client keeps respawning at random positions in an endless loop. (same happen with client on client kills)
    I would really appreaciate if anyone could tell me what I am doing wrong!

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (!IsOwner) return;
    4.  
    5.         if (health.Value <= 0) //check if dead
    6.         {
    7.             this.gameObject.transform.position = RandomPos();
    8.             health.Value = 100;
    9.         }
    10.  
    11.         Vector3 moveDir = new Vector3();
    12.  
    13.         if (Input.GetKey(KeyCode.W)) { moveDir.z = 1; }
    14.         if (Input.GetKey(KeyCode.S)) { moveDir.z = -1; }
    15.         if (Input.GetKey(KeyCode.A)) { moveDir.x = -1; }
    16.         if (Input.GetKey(KeyCode.D)) { moveDir.x = 1; }
    17.  
    18.         if (Input.GetMouseButton(0)) //shoot
    19.         {
    20.             FireServerRpc();
    21.             //cooldown
    22.         }
    23.  
    24.         float moveSpeed = 3f;
    25.         this.gameObject.transform.position += moveDir* moveSpeed * Time.deltaTime;
    26.     }
    27.  
    28.     [ServerRpc]
    29.     public void FireServerRpc()
    30.     {
    31.         RaycastHit hit;
    32.         // Does the ray intersect any objects excluding the player layer
    33.         if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit))
    34.         {
    35.             Debug.Log("Hit " + hit.collider.gameObject.ToString());
    36.             if (hit.collider.gameObject.tag == "Player")
    37.             {
    38.                 var clientHit = hit.collider.gameObject.GetComponent<NetworkObject>().OwnerClientId;
    39.                 var playerHit = NetworkManager.ConnectedClients[clientHit].PlayerObject.GetComponent<PlayerMove>();
    40.                 if (playerHit.health.Value > 0)
    41.                 {
    42.                     playerHit.health.Value -= 1;
    43.                     Debug.Log("Spieler " + clientHit + " Leben: " + NetworkManager.ConnectedClients[clientHit].PlayerObject.GetComponent<PlayerMove>().health.Value);
    44.                 }
    45.             }
    46.         }
    47.     }
     
  2. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    What networking solution are you using?
    Also, I dont see any code that syncs the movement, are you using a NetworkTransform component?
     
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,892
    It‘s NGO, there‘s a subforum for that.
    Can you also post the PlayerMove code?
     
  4. livegamezde

    livegamezde

    Joined:
    Sep 6, 2021
    Posts:
    3
    Sry, forgot to mention that. I'm using Netcode for GameObjects and a Client Network Transform to sync the players.
    The synced player movement works fine, but after a client on client kill the teleport to a random position (aka the respawn) is repeated for infinty.
     
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    The client can't change the health, not unless you've set the permission on the NetworkVariable itself. It's odd you're not seeing an error when the client tries to set it to 100.

    What I'd imagine is happening is the server is reducing the health to zero but as it's never set back to 100 check is dead is always true so the position is changing on each Update.
     
    livegamezde likes this.
  6. livegamezde

    livegamezde

    Joined:
    Sep 6, 2021
    Posts:
    3
    You are right, I got it to work by calling a SetHealth ServerRpc instead of just setting the value. Thanks for the help!
    Code (CSharp):
    1. [ServerRpc]
    2.     public void SetHealthServerRpc(ServerRpcParams serverRpcParams = default)
    3.     {
    4.         var clientId = serverRpcParams.Receive.SenderClientId;
    5.         NetworkManager.ConnectedClients[clientId].PlayerObject.GetComponent<PlayerMove>().health.Value = 100;
    6.     }
     
    cerestorm likes this.