Reading the documentation, it’s not clear to me which object references I should be able to pass around in commands. Can I pass any part (the gameobject itself, component) of a spawned object in a command? Do the have to be NetworkBehaviours?
[Command]
void CmdDoSomething(GameObject obj)
{
// do something
}
[Command]
void CmdDoSomething2(MyScriptAttachedToASpawnedObject obj)
{
// do something
}
I’m experiencing some problems with it and I don’t understand if I’m just doing something that is not supported or if there’s another problem. For example I was able to pass a NetworkIdentity reference of a runtime-spawned object but the same thing doesn’t seem to work for a scene object (null reference exception on server)
// this works for a runtime-spawned object but not if obj is the identity of a scene object
[Command]
void CmdDoSomething(NetworkIdentity obj)
{
// do something
}
You cannot pass a component of a GameObject. You can pass a GameObject with a NetworkIdentity, a NetworkIdentity itself or a NetworkInstanceId.
It shouldn’t make a difference if the object is in the scene or spawned, both can be looked up on the server by NetworkInstanceId using NetworkServer.FindLocalObject.
For those who have the same issue, here’s a workaround that works for commands in 5.1.1. Just pass the NetworkInstanceId instead of the object itself.
//instead of
CmdDoSomething(someObject);
CmdDoSomething
[Command]
public void CmdDoSomething(GameObject obj)
{
//do something with obj
}
// send only the id
CmdDoSomethingWorkaround(someObject.GetComponent<NetworkIdentity>().netId);
[Command]
public void CmdDoSomethingWorkaround(NetworkInstanceId objId)
{
GameObject obj;
if (Game.networkManager.isClient)
obj = ClientScene.FindLocalObject (objId);
else
obj = NetworkServer.FindLocalObject (objId);
//do something with obj
}
Hello! Anyone know is it optimized to pass GameObject as parametr to Commad/Rpc? I mean, I can pass like int id or string name and then find object by this value. Does it need significantly more bandwidth to pass GameObject or it uses kinda same algorithm (pass ID and then find it on other side)?
Assuming I’m right, if you were to send a GameObject as a parameter all they would do is send a reference/pointer to the object. And due to the way RAM works, I’d think a pointer on computer could point to completely different memory because you can have one person with 8GBs and another with 32GBs.
Send the netID. And then find it on the server or other clients by using NetworkServer.FindLocalObject().
As they said above, if you pass a gameobject with a NetworkIdentity to a Cmd or Rpc, it will send its netid and the server/clients on the other side will use FindLocalObject() to get the gameobject. Netid is guaranteed to be unique to an object and matches all network versions of that object.
A pointer is completely useless outside of the computer that it is associated with, even if the computers had the same amount of ram, the program is running in a completely different address space.