I wanted to post this mainly because the google info I found wasn’t that great. So - a couple of things that are quirky about NetworkViewIds and RPCs.
An RPC will accept an array of NetworkViewIDs and silently resolve every id in that array to 0. This means that if you do a NetworkView.Find() in the receiving RPC you will either get back the wrong NetworkView or an exception is thrown by the engine that you can’t catch.
If a NetworkPlayer is the server and you attempt to call an RPC using the overload that takes a NetworkPlayer argument and that argument is the server then the engine throws an exception claiming that the given NetworkPlayer is not connected to the server.
The server instance isn’t really a NetworkPlayer and I think internally the ViewId is disgarded. It’s a bit silly to send data over the network if it’s destination is the same instance as the sender.
Are you testing this in both authoritative and non-auth setups ?
The second instance came up when setting up a multiplayer level. So I had something like this:
if (Network.isServer)
{
foreach (NetworkPlayer player in connectedPlayers)
{
networkView.RPC("DoPlayerSpecificStuff", player, somePlayerSpecificArg);
}
}
This didn’t work and required a secondary check of
if (player != networkView.owner)
{
networkView.RPC(....);
}
in order to skip the RPC call if the currently enumerated NetworkPlayer is the server’s.
So - a fringe case but something that I felt was worth bringing up.
Another point I forgot to mention. NetworkView.Find() seems to throw an exception if the object with the given id is disabled. Not finding the object would seem consistent with GameObject.Find() but it’s not explicitly stated in the documentation for NetworkView.Find() and the uncatchable exception is a bummer. (I found this accidentally due to the first point because id 0 is disabled in my scene at the time that code is run.)
Here’s another one that I can’t confirm 100%, so if anyone else has seen this before feel free to post here.
If multiple GameObjects are going to send an RPC to a specific NetworkView in a given frame and the receiving GameObject is destroyed in the middle of that processing then null checks will return false (GO is not null - my guess is because Destroy calls aren’t fully processed until the end of the current frame) but the RPC will fail stating that no object with the appropriate NetworkViewID could be found. So it appears that the GameObject isn’t completely gone but its NetworkView has been removed. In my tests this seemed to really be a matter of timing and was compounded when the number of GameObjects attempting to send RPCs was increased (ie - it almost never happened with 1 but happened fairly regular with 5-10). My solution was to move the GameObject out of the frustum and wait a small amount of time before destroying the object to ensure that the RPCs were all received. Dirty, but it worked.