Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Unity MLAPI ServerRPC not getting called

Discussion in 'Netcode for GameObjects' started by LennyParisi, Apr 13, 2021.

  1. LennyParisi

    LennyParisi

    Joined:
    Mar 30, 2016
    Posts:
    4
    I'm implementing a system in which a player can pickup an item from the game world. After picking the item up, I want to destroy the game object. To do this, I figured I'd make a ServerRPC that deletes the object, but the ServerRPC is not getting called. I tried making a ClientRPC as well, but that one isn't being called either. I noticed that it only gets called when the host of the game tries to pick up the item -- any ideas on how to fix this? The documentation is pretty bare but please let me know if I missed anything. Here is my code:

    Code (CSharp):
    1.  
    2. public override void Interact(GameObject player)
    3. {
    4.     player.GetComponent<PlayerInventory>().AddItem(this.item);
    5.     Debug.Log("before");
    6.     TestClientRpc();
    7.     TestServerRpc();
    8. }
    9.  
    10.  
    11. [ServerRpc]
    12. public void TestServerRpc()
    13. {
    14.     Debug.Log("server");
    15.     // Destroy(gameObject);
    16. }
    17.  
    18. [ClientRpc]
    19. public void TestClientRpc()
    20. {
    21.     Debug.Log("client");
    22.     // Destroy(gameObject);
    23. }
    Needless to say, the output just displays 'before' -- 'server' and 'client' are never printed because the functions are never run.
     
  2. luke-unity

    luke-unity

    Unity Technologies

    Joined:
    Sep 30, 2020
    Posts:
    306
    Are these function calls on a NetworkBehaviour?
     
  3. LennyParisi

    LennyParisi

    Joined:
    Mar 30, 2016
    Posts:
    4
    Yes -- the player calls Interact on the item class, which is a child of an InteractableObject class I wrote that extends NetworkBehaviour.


    Code (CSharp):
    1. public abstract class AInteractableObject : NetworkBehaviour
    2. {
    3.     [SerializeField] protected string name;
    4.  
    5.     /// <summary>
    6.     /// Gets called when the user tries to interact with the object.
    7.     /// </summary>
    8.     public abstract void Interact(GameObject player);
    9.  
    10.     /// <summary>
    11.     /// Gets called when the user looks at the interactable object and is in range.
    12.     /// </summary>
    13.     public void OnHover(InteractableText text)
    14.     {
    15.         text.ShowText(this.name);
    16.     }
    17. }
    Code (CSharp):
    1. public abstract class PickupItem : AInteractableObject
    2. {
    3.     private AItem item;
    4.  
    5.     private void Start()
    6.     {
    7.         this.item = this.AssignItem();
    8.         this.name = this.item.Name;
    9.     }
    10.  
    11.     /// <summary>
    12.     /// Gets an item to assign to this item pickup.
    13.     /// </summary>
    14.     /// <returns></returns>
    15.     protected abstract AItem AssignItem();
    16.  
    17.     /// <summary>
    18.     /// Pickup this item up on interact.
    19.     /// </summary>
    20.     public override void Interact(GameObject player)
    21.     {
    22.         player.GetComponent<PlayerInventory>().AddItem(this.item);
    23.         Debug.Log("before");
    24.         TestClientRpc();
    25.         TestServerRpc();
    26.     }
    27.  
    28.  
    29.     [ServerRpc]
    30.     public void TestServerRpc()
    31.     {
    32.         Debug.Log("server");
    33.         // Destroy(gameObject);
    34.     }
    35.  
    36.     [ClientRpc]
    37.     public void TestClientRpc()
    38.     {
    39.         Debug.Log("client");
    40.         // Destroy(gameObject);
    41.     }
    42. }
    43.  
    Code (CSharp):
    1. /// <summary>
    2. /// Represents an item in the game. It has a name and a description.
    3. /// </summary>
    4. public abstract class AItem
    5. {
    6.     private readonly string name;
    7.     private readonly string description;
    8.  
    9.     /// <summary>
    10.     /// Constructs an abstract item.
    11.     /// </summary>
    12.     /// <param name="name">The name of the item</param>
    13.     /// <param name="description">The description for the item</param>
    14.     public AItem(string name, string description)
    15.     {
    16.         this.name = name;
    17.         this.description = description;
    18.     }
    19.  
    20.     public string Name { get => name; }
    21.     public string Description { get => description; }
    22. }
    23.  
     
  4. dante66

    dante66

    Joined:
    Mar 25, 2014
    Posts:
    8
    Did you check the logs?
    You may need to add the following attribute to your ServerRpc:

    Code (CSharp):
    1. [ServerRpc(RequireOwnership = false)]
    2.  
    if your player is not the owner of the item (which I believe is the case)
     
    Vulcore and LennyParisi like this.
  5. LennyParisi

    LennyParisi

    Joined:
    Mar 30, 2016
    Posts:
    4
    OMG thank you so much it worked -- I never saw anything about this in the docs!
     
  6. dante66

    dante66

    Joined:
    Mar 25, 2014
    Posts:
    8
    Yes, the documentation is pretty poor. I had the issue myself, and in the player.log there was an error about this missing attribute.
     
    LennyParisi likes this.
  7. Vulcore

    Vulcore

    Joined:
    Nov 17, 2016
    Posts:
    2
    Thank you for this. I could not work out why some rpc calls where not working despite having done everything as per the documentation.
     
unityunity