Search Unity

UNET Multiplayer-How can a GameObject be destroyed by the Client and be sync/updated to host/server?

Discussion in 'UNet' started by petroslouca, May 28, 2019.

?

UNET Multiplayer-How can a GameObject be destroyed by the Client and be sync/updated to host/server?

Poll closed Nov 28, 2019.
  1. Destroy function

    0 vote(s)
    0.0%
  2. Server Update

    0 vote(s)
    0.0%
  3. Server Sync

    0 vote(s)
    0.0%
  4. Client Command send

    1 vote(s)
    100.0%
Multiple votes are allowed.
  1. petroslouca

    petroslouca

    Joined:
    May 17, 2018
    Posts:
    14
    In a MatchMaker multiplayer game (Unity version 2018.1.0f2), when a GO is destroyed on the host, that GO is also destroyed on the client(s) but the other way round cannot be accomplished, here is my script code below, attached to the GO that is needed to be destroyed (the GO has "Server Only" and "Local Player Authority" options unchecked and "Network Transform Send Rate" to 9):

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Networking;

    public class GameObjectDestroyScript : NetworkBehaviour
    {

    [SerializeField]
    GameObject GOobject;

    private void OnMouseDown()
    {
    Destroy(GOobject);
    }

    }

    I need a GO to be destroyed by the client(s) and be sync/updated to the server/host, in order to subsequently sync/update the clients' GO!

    Please ask for any feedback/info that you may need in order to help me.


    Thank you for your time!
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Send a Unet Message or a Command to the host to tell the host to destroy the object. Don't destroy it on the client.
     
  3. petroslouca

    petroslouca

    Joined:
    May 17, 2018
    Posts:
    14
    Thank you for your reply, here is the part of the code in player's script for INSTATIATING the GameObject over the network (no problem with that):

    //Declaration in the beginning of the player's script
    GameObject goItem;

    // Instatiation of the GO over the network
    [Command]
    public void CmdItemSpawn()
    {
    GameObject goItem = (GameObject)Instantiate(ItemPrefab);
    // var goItem = Instantiate(ItemPrefab) as GameObject; NOT USED

    //Spawn the Item on the server/clients
    NetworkServer.Spawn(goItem);
    }

    and here is the added code for destroying the GO, called from UPDATE function of the player' script, i.e. CmdItemDestroy(); still with no success:

    // Destroying the GO over the network, command to server and then sync/update from server to client(s)
    [Command]
    public void CmdItemDestroy()
    {
    //Destroy the Item on the server/clients, "Destroy(go.Item);" was also tested with no success
    NetworkServer.Destroy(goItem);
    }

    Also, how the OnMouseDown() function can be used/called in order to destroy the GO, as can only be included the GO prefab's script? All code above is included in player's script (INSTANTIATION part works fine on server and clients).
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Add a Debug.Log statement to CmdItemDestroy() to verify it is actually being called on the server when you think it should be. You might also want to verify that goItem isn't null, or is still pointing to the same object you expect it to.

    edit: Just noticed in your instantiate code you are declaring a local GameObject goItem to that method. So goItem in CmdItemDestroy() isn't going to be the same reference.
     
  5. petroslouca

    petroslouca

    Joined:
    May 17, 2018
    Posts:
    14
    Thank you, could you indicate how to achieve having the same reference? Just write a small simple example for that to understand what you mean.
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Supposedly you can send a GameObject reference directly in a Command or ClientRpc as long as it has already been spawned by the server and has an attached NetworkIdentity component. That is according to the documentation. I tried it once, it didn't immediately work for me, but that was when I was just starting learning Unet at the time so I probably had done something wrong. So you might want to give that a try.

    I generally use cached references on the server side, or an alternative identifier, when I wanted to do something like this. If you just removed the goItem declaration from your first line of CmdItemSpawn(), you'd be using a cached reference (as long as you only call CmdItemSpawn once). My guess is that was actually your intention.

    So this:
    Code (csharp):
    1. GameObject goItem = (GameObject)Instantiate(ItemPrefab);
    Change to this:
    Code (csharp):
    1. goItem = (GameObject)Instantiate(ItemPrefab);
    Note though that Unet has been deprecated for a while, so it is not a good idea to invest a lot of time learning it. I'd change to another API.
     
  7. petroslouca

    petroslouca

    Joined:
    May 17, 2018
    Posts:
    14
    Thank you very much for your guide lines, it worked!!!

    The thread can now close.