Search Unity

Can't destroy object on network that's gotten from Raycast

Discussion in 'Multiplayer' started by Wbjpen, Apr 9, 2017.

  1. Wbjpen

    Wbjpen

    Joined:
    Dec 8, 2015
    Posts:
    1
    A player object does this to instantiate the block on theirs and other clients.
    Code (CSharp):
    1.  
    2.     [ClientRpc]
    3.     private void RpcPlaceBlock(GameObject prefab) {
    4.         GameObject obj = Instantiate(prefab);
    5.         NetworkServer.Spawn(block.gameObject);
    6.     }
    The problem comes when I try to get the player object to trigger destroying the object.
    The object to destroy is gotten through a Raycast that returns the object that the player is looking at. I then try to pass that to "NetworkServer.Destroy(object);" inside a Rpc to remove it from all clients. That's where it doesn't work.

    The only thing I can think of is the GameObject I get from the Raycast is unique from all the other copies on the server/other clients, so I'm trying to destroy something that doesn't exist on other clients.
     
  2. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    Yeah there's a few issues here. Firstly, make sure that you understand the difference between "client" and "server". To give you a rough idea: a "client" is a player, generating input from some form of control device (keyboard + mouse, gamepad etc) and making requests to the server. The "server" is a remote peer/dedicated computer receiving input/requests from clients, and making authoritative decisions.

    RPCs originate on the server-side from objects that exist on the server. Invoking an RPC method on the server-side results in the method being called on the same object in all clients.

    Commands originate from the client-side, on an object that has been spawned over the network. Invoking a Command method on the client will result in the method being called on the same object on the server side.

    NetworkServer in general is a class that is to be used on the server only. Whether this is a peer-host (in the peer-to-peer server model where one of your players acts as the server) or a dedicated server (the client-server model), you would only use this class on the server-side. So, your NetworkServer.Spawn method would only be called on the server-side. Never on the client-side.

    Your code is a brilliant example of how to get all of the above mixed up... an RPC (which is called on the client...) using NetworkServer.Spawn (which should only be called on the server...).

    As a side note, and once the above makes sense, it's worth noting that you don't need to notify the client that an object has been spawned (in an RPC for example). By calling NetworkServer.Spawn on a registered object instantiated on the server (registered either within the NetworkManager, or via ClientScene.RegisterPrefab), the object will automatically be spawned on all clients. Calling Destroy on the same object (on the server side!) will result in the object being removed from all clients.

    Hopefully this helps. Let me know if you're still stuck.