Unity 5.5.0f3 - Updating an object with ClientRpc throws "Found no behaviour for Rpc call..."

Viewed 193

I'm working on a teammatch game. Each team has it's own spawn and the objective is to destroy the other team's spawn. The spawns are setup in the network in form of 3 objects - an actual spawn (referenced later on to as the physical spawn), visible only to the server, an object called MapManager present in both client and server, that acts as a messenger through the Rpc calls and a simple graphic of spawn (referenced later on to as the visual spawn), present on the client and the server's local player.

NetworkIdentity settings for each object respectively:

  • Server Only,
  • Local Player Authority,
  • None - is a MonoBehaviour.

The physical spawn judges whether was any damage dealt to the spawn and if yes - sets the flag isHealthChanged to true.

public class SpawnerServer : NetworkBehaviour {
    //used to determine whether has the health changed
    bool isHealthChanged = false;
    //indicates the team of this spawner via enum state
    public Data.teams myTeamEnum;
    ...
    public RectTransform healthBar;

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //Checking whether the bullet wll damage the spawn
        OnChangeHealth(healthPoints);
    }
    //if the health changed, change the healthbar as well
    public void OnChangeHealth(float healthPoints)
    {
        if (isServer)
        {
            ...
            isHealthChanged = true;
        }
    }
     //returns the deltaSize of the healthbar
     public Vector2 GetHealthbarSizeDelta()
    {
        return healthBar.sizeDelta;
    }
    //switches the healthChanged bool back to false. Called by the MapManager
    public void UncheckHealthChanged()
    {
        isHealthChanged = false;
    }
    //returns the state of the healthChanged bool
    public bool IsHealthChanged()
    {
        return isHealthChanged;
    }
}

The MapManager checks for the state of the flag in both physical spawns (checks only on the server) and upon detecting the true value:

  • resets the flag to false,
  • gets the width of the healthbar,
  • passes the info about the new width of the healthbar and the number of spawn to RPC call RpcChangeSpawnersHealthClients(), which calls function responsible for updating the data of the transform of the healthbar of the visual spawn.

    public class ClientSpawnControl : NetworkBehaviour {
    //the references to scripts of the server spawns, required for checking whether has
    //the state of any of the spawns changed
    public SpawnerServer serverSpawn1;
    public SpawnerServer serverSpawn2;
    //the references to spawns that belong to the clients
    public SpawnerClient clientSpawn1;
    public SpawnerClient clientSpawn2;
    
    //acts as a messenger that forces change of spawn healthbars in clients
    [ClientRpc]
    private void RpcChangeSpawnersHealthClients(int whatTeam, float healthChangeDelta)
    {
        if(clientSpawn1 != null)
        {
            if (whatTeam == (int)clientSpawn1.myTeam)
            {
                clientSpawn1.OnChangeHealth(healthChangeDelta);
                return;
            }
        }
        if(clientSpawn2 != null)
        {
            if (whatTeam == (int)clientSpawn2.myTeam)
            {
                clientSpawn2.OnChangeHealth(healthChangeDelta);
                return;
            }
        }
    }
    // Update is called once per frame
    void Update () {
        if (!isServer)
            return;
        if(serverSpawn1.IsHealthChanged())
        {
            serverSpawn1.UncheckHealthChanged();
            RpcChangeSpawnersHealthClients((int)serverSpawn1.myTeamEnum, serverSpawn1.GetHealthbarSizeDelta().x);
        }
        if (serverSpawn2.IsHealthChanged())
        {
            serverSpawn2.UncheckHealthChanged();
            RpcChangeSpawnersHealthClients((int)serverSpawn2.myTeamEnum, serverSpawn2.GetHealthbarSizeDelta().x);
        }
    
    }
    

This is where the exception is thrown: "Found no behaviour for incoming [ClientRpc:InvokeRpcRpcChangeSpawnersHealthClients] on TeamSelector (UnityEngine.GameObject), the server and the client should have the same NetworkBehaviour instaces..."

The error is quite interesting, since the mentioned TeamSelector has literally nothing to do with the spawners updating. It is used at the beggining, to initialize the team data of the players, nothing more. Even more - one of the physical spawns is somehow spawned on the client as well, though if I remember correctly the Server Only option should prevent such behavior and I do not try to create the object across the network anyhow.

Earlier I tried to spawn the visual spawns armed with NetworkBehaviour and NetworkIdentity - was getting error about that these objects cannot be spawned in the client, even if I registered the objects in the Network Manager and even used the method ClientScene.RegisterPrefab(). Made every possible combination of the two - situation did not change. Later I rearranged the visual spawns to their current form and tried calling the RPC call from the MapManager from the physical spawns as soon as they detected change in health. Got similiar exception thrown at the client to the one quoted above, but with name of one of the physical spawns in the place of the TeamSelector object. Search for solutions did not bring up anything that would work, for example I do not have any methods that have duplicate names but belong to different namespaces.

I do not even really know where to search for the source of the problem. After over 3 days of arguing with Unity I feel like it just doesn't want me to create that game. Does anybody know what can cause the problem?

I'm terribly sorry for the length of this post, but I have no idea how to describe this problem in shorter way.

0 Answers
Related