Search code examples
c#unity-game-enginenetwork-programmingrpcmultiplayer

Object instantiated by host not seen on client


I have an issue where a ServerRpc to instantiate an object is not visible to clients when instantiated by host. However, if the client instantiates an object, the host client is able to see it. Here is my code, and the prefabs are fishnet network objects.

public override void OnStartClient()
    {
        base.OnStartClient();
        if (!base.IsOwner)
        {
            enabled = false;
            return;
        }
    }
[ServerRpc(RequireOwnership = false)]
    void DropItemsRPC(GameObject prefab, Vector3 position)
    {
        GameObject drop = Instantiate(prefab, position, Quaternion.identity, worldObjectHolder);
        ServerManager.Spawn(drop);
    }


Solution

  • Explanation: you are using (RequireOwnership = false) which allows method to run on clients too. so removing it will allow method to run only on server, the next thing is to spawn object where object type must be NetworkObject for convince and to instiantiate need to use fishnet instiantiation just to stay legal and to pool it; so on dissconnect object will not destroy and we can have it in scene again on reconnection.

    if those 2 things are clear then we can move on one last thing where we actually spawn object on server. while creating it on server we can either pass NetworkConnection to give ownership to certain client, if pass null server is owner. After spawning we need to tell fishnet to match the scene so we use AddOwnerToDefaultScene to do that. (personally I don't know much about this scene thing, I am assumming it).

    I am bad at explaining things so just use Below code. It will work for sure.

    Namespace require :

    using FishNet;
    

    Code :

    [ServerRpc]
    void DropItemsRPC(NetworkObject prefab, Vector3 position)
    {
        var _networkManager = InstanceFinder.NetworkManager;
        var drop = _networkManager.GetPooledInstantiated(prefab,position,Quaternion.identity,true);
        _networkManager.ServerManager.Spawn(drop);
        _networkManager.SceneManager.AddOwnerToDefaultScene(drop);
    }