In game, whenever a character “picks up” an “item” (gameobject), I use NetworkServer.Destroy() to remove it from the game.
This works on the Server/Host, but does nothing when the client does the same thing. (The host correctly tells everyone the itemGameObject is destroyed when the host’s character ‘picks up’ an item. All clients are updated correctly by the server. However, when the Client’s character picks up an item, it only destroys it on the Client but NOT the server- so it is not updated/synced.)
I had this same problem with Instantiating gameobjects (in game, characters “dropping items”) and the solution was to make instantiation in a command.
Shouldn’t calling NetworkServer.Destroy(gameObject) on a client, tell the server to destroy it / update for everyone? (The server is also the first player, while the client is the second player. No need for authoritative/standalone server).
The documentation for this new Unet is seriously lacking, I’ve spent so much time in futility >_<
In an authoritative server situation, like with unity networking, the client should not be able to destroy an object. Instead, it can request the server to do so, but the server must ultimately be the one to do it.
If you want the client to decide to destroy something, it can put in a request via a command. You can identify a networked object using its NetworkInstanceId. Something like this might suit.
[Command]
public void CmdDoThing(NetworkInstanceId netID)
{
GameObject theObject = NetworkServer.FindLocalObject(netID);
...
}
// Call the above from a client. netId is accessible via NetworkBehaviour
CmdDoThing(netId);
I don’t know how NetworkServer.FindLocalObject is implemented. I would love to know if it is efficient to use or not. I’m hoping it’s based on a dictionary or something similar.
I tried something like this already and to no avail. Perhaps you can help me figure out where I went wrong? I forgot how I did it, but I just tried again and am getting an error.
Log outputs the correct ‘netID’ (ex. “4”).
Then Cmd_DestroyThis(networkIdentity.netID) results in the following error:
“There is no NetworkIdentity on this object. Please add one.”
public NetworkIdentity networkIdentity; //linked in the Inspector, since I kept getting a null reference. Tried this with GetComponent<NetworkIdentity> as well.
[Command]
void Cmd_DestroyThis(NetworkInstanceId netID)
{
GameObject theObject = NetworkServer.FindLocalObject(netID);
NetworkServer.Destroy(theObject);
}
I honestly don’t care HOW I do it. If it’s easier to simply request the server to do so. However, I don’t seem to be able to accomplish this either.
4 hours and 30 minutes trying to figure out how to destroy an object with Unet. Urgh…
Ah I see. I was doing a lot of this using a parent’s NetworkIdentity while the gameobject with this script did not have its own NetworkIdentity. Easy fix.
Can also explain why so many of my attempts did not at all work as they “should have”.
Anyway, when I send the [Command] on the Client, it still doesn’t destroy the gameobject. In game, this means I can pick up an infinite amount of the item (on the client).
Trying to send command for non-local player.
UnityEngine.Networking.NetworkBehaviour:SendCommandInternal(NetworkWriter, Int32, String)
NetworkDestroyBool:CallCmd_DestroyThis(NetworkInstanceId)
I’m going to close this and re-ask the question in a better context. I clearly have no idea what I’m doing despite my attempts at understanding the documentation & sample projects. (I don’t need the client to delete objects. I can simply request the server to delete them.)
Yeah, the client can’t remove objects but the host can… was there an easy fix to this? I’ve tried alot of things but I just cant think of any other ideas to fix this myself.
with my last good ‘fix’ I now have all the commands and such on the player, but now the client get an “Object reference not set to an instance of an object” error while the player tries to interact with it ingame. ( and it still doesnt destroy the object )
I honestly do not know. I don’t use UNET, I use Forge Remastered.
Perhaps if you pasted your code, someone more experienced with UNET could help? I understand network logic, but don’t really know of UNET specific nuances.
I’m having the same problem you had. In my case I have my script on the game object being picked up. I have no commands anywhere because I don’t know where to place them. The server/host gets the pickup just fine but like in your situation when done on the client it seems outta sync? Any thoughts on how to fix it?
Make sure your object is actually spawned, and the commands passed have authority.[/QUOTE]
Thanks the object is now destroying on the server and client, however i ran into a problem. When the player overlaps the other player the client disappears.
I have gone through your past conversation and I have followed the recommended steps. I still have problem with client to server sync/update.
In a MatchMaker multiplayer game (Unity version 2018.1.0f2), when the 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 unticked 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;