Search Unity

Question Host is able to call the ServerRpc but Client is not

Discussion in 'Netcode for GameObjects' started by ParagonSe7en, Sep 15, 2022.

  1. ParagonSe7en

    ParagonSe7en

    Joined:
    Mar 27, 2018
    Posts:
    2
    I'm new to netcode so I may be doing something fundamentally wrong but with the code below I am able to move my player prefab as the host but not as the client. The client will hit a breakpoint on the FixedUpdate() function where the call to "MoveServerRpc();" is made but it will never step into that function for some reason.

    The player prefab this script is on contains these components (Transform, Sprite Renderer, RigidBody, Player Input (new input system), Capsule Collider, NetworkObject, NetworkTransform, and a Network Rigidbody).

    Also the client can see the host move so I know it is getting information from the server but for some reason it won't step into that MoveServerRpc function to send the information to the server. Any ideas?

    Code (CSharp):
    1. using Unity.Netcode;
    2. using UnityEngine;
    3. using UnityEngine.InputSystem;
    4.  
    5. public class MovementScript : NetworkBehaviour
    6. {
    7.   [SerializeField]
    8.   Rigidbody rb;
    9.  
    10.   public float speed;
    11.   public float leftStick_X;
    12.   public float leftStick_Y;
    13.   public NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>();
    14.  
    15.   void Start()
    16.   {
    17.     rb = GetComponent<Rigidbody>();
    18.     if (IsLocalPlayer)
    19.     {
    20.       gameObject.GetComponentInChildren<Camera>().enabled = true;
    21.     }
    22.     else
    23.     {
    24.       gameObject.GetComponentInChildren<Camera>().enabled = false;
    25.     }
    26.   }
    27.   void FixedUpdate()
    28.   {
    29.     if (IsServer)
    30.     {
    31.       Position.Value = transform.position;
    32.     }
    33.     if (IsLocalPlayer)
    34.     {
    35.       MoveServerRpc();
    36.     }
    37.     transform.position = Position.Value;
    38.   }
    39.  
    40.   [ServerRpc(RequireOwnership = false)]
    41.   public void MoveServerRpc(ServerRpcParams serverRpcParams = default)
    42.   {
    43.     rb.AddForce((leftStick_Y * speed * 1000) * Time.deltaTime * transform.forward);
    44.     rb.AddForce((leftStick_X * speed * 600) * Time.deltaTime * transform.right);
    45.     Position.Value = transform.position;
    46.   }
    47.  
    48.   void OnMove(InputValue value)
    49.   {
    50.     if (IsLocalPlayer)
    51.     {
    52.       Debug.Log("pressed");
    53.       Vector2 playerMove = value.Get<Vector2>();
    54.       //Movement
    55.       leftStick_X = playerMove.x;
    56.       leftStick_Y = playerMove.y;
    57.     }
    58.   }
    59. }
    60.  
     
  2. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    Last edited: Sep 15, 2022
  3. ParagonSe7en

    ParagonSe7en

    Joined:
    Mar 27, 2018
    Posts:
    2
    It's a 3d game that uses 2d sprites for just the player prefab ( could be part of the problem ).

    My initial thoughts have been that the RigidBody in general isn't working properly but after adding NetworkRigidbody script to the Player Prefab object I was able to see things like collisions working between the host and the client.

    Is there something wrong about the way I am storing the input values? Should leftStick_X and leftStick_Y be turned into network variables and sent via an ServerRpc call? It seemed like overkill to me but it's something I haven't quite tried yet.

    The last hailmary I can think of is that there is only one other custom script on the main Player Prefab object that is modifying the transform.rotation and has no references to the rigidbody. It uses a path library to keep the player rotated in the forward direction on a road. I made it inherit NetworkBehaviour just in case though. Here is that script which should be effecting the Clients ability to move:


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using PathCreation;
    5. using Unity.Netcode;
    6.  
    7. public class RoadRotationAlignment : NetworkBehaviour
    8. {
    9.   public PathCreator path1;
    10.   public PathCreator path2;
    11.   [SerializeField]
    12.   private bool isCamera = false;
    13.   [SerializeField]
    14.   private GameObject player;
    15.  
    16.   private void Awake()
    17.   {
    18.     path1 = GameObject.FindGameObjectWithTag("path1").GetComponent<PathCreator>();
    19.     path2 = GameObject.FindGameObjectWithTag("path2").GetComponent<PathCreator>();
    20.   }
    21.  
    22.   void Start()
    23.   {
    24.     transform.rotation = Quaternion.Euler(0, path1.path.GetRotationAtDistance(path1.path.GetClosestDistanceAlongPath(transform.position), EndOfPathInstruction.Stop).eulerAngles.y, 0);
    25.   }
    26.  
    27.   // Update is called once per frame
    28.   void FixedUpdate()
    29.   {
    30.     //check which path we are on/closest to and only check if the beginning of path2 has been reached and is not still 0
    31.     if (Vector3.Distance(path1.path.GetClosestPointOnPath(transform.position), transform.position) < Vector3.Distance(path2.path.GetClosestPointOnPath(transform.position), transform.position))
    32.     {
    33.       Debug.Log("Path 1 chosen. Path 1 Value: " + Vector3.Distance(path1.path.GetClosestPointOnPath(transform.position), transform.position) + " Path 2 value: " + Vector3.Distance(path2.path.GetClosestPointOnPath(transform.position), transform.position));
    34.       if (isCamera == false)
    35.       {
    36.         transform.rotation = Quaternion.Euler(0, path1.path.GetRotationAtDistance(path1.path.GetClosestDistanceAlongPath(transform.position), EndOfPathInstruction.Stop).eulerAngles.y, 0);
    37.       }
    38.       else
    39.       {
    40.         Vector3 desiredRotation = new Vector3(0, path1.path.GetRotationAtDistance(path1.path.GetClosestDistanceAlongPath(transform.position), EndOfPathInstruction.Stop).eulerAngles.y, 0);
    41.         Vector3 smoothedRotation = Vector3.Lerp(transform.rotation.eulerAngles, desiredRotation, 3000000 * Time.deltaTime);
    42.         transform.rotation = Quaternion.Euler(smoothedRotation);
    43.       }
    44.     }
    45.     else if (Vector3.Distance(path1.path.GetClosestPointOnPath(transform.position), transform.position) > Vector3.Distance(path2.path.GetClosestPointOnPath(transform.position), transform.position))
    46.     {
    47.       Debug.Log("Path 2 chosen. Path 1 Value: " + Vector3.Distance(path1.path.GetClosestPointOnPath(transform.position), transform.position) + " Path 2 value: " + Vector3.Distance(path2.path.GetClosestPointOnPath(transform.position), transform.position));
    48.       if (isCamera == false)
    49.       {
    50.         transform.rotation = Quaternion.Euler(0, path2.path.GetRotationAtDistance(path2.path.GetClosestDistanceAlongPath(transform.position), EndOfPathInstruction.Stop).eulerAngles.y, 0);
    51.       }
    52.       else
    53.       {
    54.         Vector3 desiredRotation = new Vector3(0, path2.path.GetRotationAtDistance(path2.path.GetClosestDistanceAlongPath(transform.position), EndOfPathInstruction.Stop).eulerAngles.y, 0);
    55.         Vector3 smoothedRotation = Vector3.Lerp(transform.rotation.eulerAngles, desiredRotation, 3000000 * Time.deltaTime);
    56.         transform.rotation = Quaternion.Euler(smoothedRotation);
    57.       }
    58.     }
    59.   }
    60. }
    61.  
     
  4. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    You would definitely need the NetworkRigidbody component to sync physics collisions.

    Have you seen our ClientPlayerMove.cs script for our client-driven sample?
    We're using the Client Network Transform component, as well as a Character Controller and NetworkObject. If you are not doing Client-driven movements, try the NetworkTransform component.
     
  5. lavagoatGG

    lavagoatGG

    Joined:
    Apr 16, 2022
    Posts:
    229
    Maybe you havn't spawned the network object on the client player?