Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Host moving all players

Discussion in 'Netcode for GameObjects' started by Natank25, Jun 8, 2022.

  1. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    I started creating a game in multiplayer, I added to character mouvement with the new input system and now, when the host uses wasd, he also ove every other players connected. To do this, I followed the Unity tutorial "building on "Hello World"" and I changed the GetRandomPositionOnPlane with this :

    Code (CSharp):
    1.         Vector2 input = playerInput.actions["HorizontalMovement"].ReadValue<Vector2>();
    2.         move = new Vector3(input.x, 0f, input.y);
    3.         move.y = 0f;
    4.  
    5.         newPos = transform.position + move * Time.deltaTime * speed;
    6.  
    7.         return newPos;
    Anyone can help me ?
     
  2. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    It's because every player object (which is replicated for all other clients) listens for input. But instead, you only want your own player object to listen for your input. So the solution is to put this code inside
    if (IsLocalPlayer) {...}
    .
     
  3. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    I did that and now the host can only moves his player but not the client.
     
  4. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    Does the player have authority to move their client? Do you use NetworkTransform components (only server is allowed to move them) or ClientNetworkTransforms (only the owning client is allowed to move them)? See the many threads about this in this forum. ;)
     
  5. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    In the component list i don't see any ClientNetworkTransform. Is it normal ?
     
  6. edin97

    edin97

    Joined:
    Aug 9, 2021
    Posts:
    58
    Because it's hidden in one of the samples, you can download it by following the doc, at the very bottom (under "ClientNetworkTransform") they explain how to download it from the sample, once you got it, just replace "NetworkTransform" by the "ClientNetworkTransform" on your player
     
  7. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    After the download, I restarted Unity Editor 2 times and I don't have any samples except Bootstrap and I don't have any ideas why.
     
  8. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
  9. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    That’s where I downloaded it from
     
  10. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    It doesn't show up under Samples, Multiplayer Samples Utilities is a separate package, check it's listed under your installed packages. It should be available when you Add Component to your game object.
     
  11. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    Even with ClientNetworkTransform, the clients can't move their players
     
  12. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    Remove the NetworkTransform if there is one. Try changing the transform values directly in the editor, on both client and server and see if there's any movement.
     
  13. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    Because Unity doesn't allow you to uses NetworkTransform and ClientNetworkTransform that wasn't possible and how do I do to use host and client at the same time with acces of the inspector each ? (maybe this isn't english but I hope your understood)
     
  14. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
  15. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    I get the error "Only the owner can invoke a ServerRpc that requires ownership!" only on the editor with client chosen but i don't know how to fix it.
     
  16. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    Is the ServerRpc not on the player, the client would normally have ownership of it. You can get around the error with [ServerRpc(RequireOwnership = false)].
     
  17. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    It still doesn't work but I don't get the error anymore
     
    Last edited: Jun 10, 2022
  18. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    Check that the NetworkObject component of your client game object has a NetworkObjectId, the number should match the object on the server.

    Did you try changing the transform values in the editor?
     
  19. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    Changing the values in the editor work, the NetworkObject has an id but the Player Input Component has a debug section for the host but not for the client.
     
    Last edited: Jun 11, 2022
  20. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    It works as in changes on the transform on the client are reflected on the server transform?

    ClientNetworkTransform uses RPC's so if they are working so should your component script with the RPC in it. Does your script inherit from NetworkBehaviour? Are you sure the RPC is being called, even if it's not being sent to the server it should still run locally, put a debug log in there to be sure.

    You might want to share the whole of the script your using to help see what's going on.
     
  21. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    By the server and client transform you mean the characters ?

    My script inherit from NetworkBehaviour. The RPC is being called.

    My whole script of the movement :
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.InputSystem;
    3. using Unity.Netcode;
    4.  
    5. public class Movement : NetworkBehaviour
    6. {
    7.  
    8.     [SerializeField]
    9.     private PlayerInput playerInput;
    10.  
    11.     private Vector3 move;
    12.  
    13.     [SerializeField] float speed = 11f;
    14.     private Vector3 newPos;
    15.  
    16.  
    17.     [SerializeField] LayerMask groundMask;
    18.  
    19.     private NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>();
    20.  
    21.     public void Move()
    22.     {
    23.         if (NetworkManager.Singleton.IsServer)
    24.         {
    25.             var randomPosition = NewPos();
    26.             transform.position = randomPosition;
    27.             Position.Value = randomPosition;
    28.         }
    29.         else
    30.         {
    31.             SubmitPositionRequestServerRpc();
    32.         }
    33.     }
    34.  
    35.     [ServerRpc(RequireOwnership = false)]
    36.     void SubmitPositionRequestServerRpc()
    37.     {
    38.         Position.Value = NewPos();
    39.     }
    40.  
    41.     private Vector3 NewPos()
    42.     {
    43.         if (IsLocalPlayer)
    44.         {
    45.             Vector2 input = playerInput.actions["HorizontalMovement"].ReadValue<Vector2>();
    46.             move = new Vector3(input.x, 0f, input.y);
    47.             move.y = 0f;
    48.  
    49.             newPos = transform.position + move * Time.deltaTime * speed;
    50.  
    51.             return newPos;
    52.         }
    53.         else
    54.         {
    55.             return Vector3.zero;
    56.         }
    57.     }
    58.  
    59.     void Update()
    60.     {
    61.         Move();
    62.     }
    63.  
    64.     private void Awake()
    65.     {
    66.         transform.position = new Vector3(0, 1, 0);
    67.     }
    68. }
     
  22. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    You don't want to use the RPC at all as the ClientNetworkTransform is passing the position to the server for you. Just set the transform position on the client and it should be reflected on the server transform.
     
  23. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    So I just need to remove the
    if(NetworkManager.Signleton.Server)

    and it should work ?
     
  24. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    Definitely get rid of that, at the moment only the host can move their player object. Also remove the SubmitPositionRequestServerRpc() call.
     
  25. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    Now both client and server can move their players but I get this error :
    InvalidOperationException: Client is not allowed to write to this NetworkVariable
    only on the editor wich runs client mode
     
  26. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    Remove the Position variable.
    Code (CSharp):
    1. private NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>();
    It should no longer be required.
     
  27. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    And I also remove it in Move() ?
     
  28. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    Yes. Position doesn't look to be used elsewhere so it should be safe to remove it.
     
  29. Natank25

    Natank25

    Joined:
    Feb 10, 2022
    Posts:
    26
    It works without any errors! Thank you for your time and your help!
     
  30. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    648
    You're welcome. :)