Unity MLAPI ServerRPC not getting called

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:

public override void Interact(GameObject player)
{
    player.GetComponent<PlayerInventory>().AddItem(this.item);
    Debug.Log("before");
    TestClientRpc();
    TestServerRpc();
}


[ServerRpc]
public void TestServerRpc()
{
    Debug.Log("server");
    // Destroy(gameObject);
}

[ClientRpc]
public void TestClientRpc()
{
    Debug.Log("client");
    // Destroy(gameObject);
}

Needless to say, the output just displays ‘before’ – ‘server’ and ‘client’ are never printed because the functions are never run.

Are these function calls on a NetworkBehaviour?

Yes – the player calls Interact on the item class, which is a child of an InteractableObject class I wrote that extends NetworkBehaviour.

public abstract class AInteractableObject : NetworkBehaviour
{
    [SerializeField] protected string name;

    /// <summary>
    /// Gets called when the user tries to interact with the object.
    /// </summary>
    public abstract void Interact(GameObject player);

    /// <summary>
    /// Gets called when the user looks at the interactable object and is in range.
    /// </summary>
    public void OnHover(InteractableText text)
    {
        text.ShowText(this.name);
    }
}
public abstract class PickupItem : AInteractableObject
{
    private AItem item;

    private void Start()
    {
        this.item = this.AssignItem();
        this.name = this.item.Name;
    }

    /// <summary>
    /// Gets an item to assign to this item pickup.
    /// </summary>
    /// <returns></returns>
    protected abstract AItem AssignItem();

    /// <summary>
    /// Pickup this item up on interact.
    /// </summary>
    public override void Interact(GameObject player)
    {
        player.GetComponent<PlayerInventory>().AddItem(this.item);
        Debug.Log("before");
        TestClientRpc();
        TestServerRpc();
    }


    [ServerRpc]
    public void TestServerRpc()
    {
        Debug.Log("server");
        // Destroy(gameObject);
    }

    [ClientRpc]
    public void TestClientRpc()
    {
        Debug.Log("client");
        // Destroy(gameObject);
    }
}
/// <summary>
/// Represents an item in the game. It has a name and a description.
/// </summary>
public abstract class AItem
{
    private readonly string name;
    private readonly string description;

    /// <summary>
    /// Constructs an abstract item.
    /// </summary>
    /// <param name="name">The name of the item</param>
    /// <param name="description">The description for the item</param>
    public AItem(string name, string description)
    {
        this.name = name;
        this.description = description;
    }

    public string Name { get => name; }
    public string Description { get => description; }
}

Did you check the logs?
You may need to add the following attribute to your ServerRpc:

[ServerRpc(RequireOwnership = false)]

if your player is not the owner of the item (which I believe is the case)

3 Likes

OMG thank you so much it worked – I never saw anything about this in the docs!

Yes, the documentation is pretty poor. I had the issue myself, and in the player.log there was an error about this missing attribute.

1 Like

Thank you for this. I could not work out why some rpc calls where not working despite having done everything as per the documentation.