RPC called with a viewID, reaching server with a different viewID

Hi everyone,

First off, I’ve done some research on this issue already but didn’t find anything specific to my particular problem, so after a couple of days trying to figure this out, I’ve finally decided to ask a question. So here it goes:

I have a Weapon Data object in the scene, instantiated via prefab both in the server and client. This object has a script that, after the first level is loaded, sends an RPC from the client to the server telling him which weapons does the player possess. In short:

if (Network.isClient)
{
     networkView.RPC("S_FillWeaponLists", RPCMode.Server, "sword1");
}

This RPC is of course found in the same script:

[RPC]
void S_FillWeaponLists(string weaponToAdd, NetworkMessageInfo info)
{
	if (weaponToAdd == "sword1")
	{
		possessedSwords.Add(sword1);
	}
}

Quite straightforward. The problem here is that the server seems to be getting the RPC with the wrong viewID (0), and thus it can’t execute it, since it doesn’t find the relevant networkview. Now, I’ve checked and double-checked; at the point of calling the RPC, both the client’s and server’s Weapon Data networkview has a viewID of 3.

It would seem that the RPC is somehow changing its ID during the trip, and reaching the server with an ID of 0. How is this possible? I’m trying to understand what could cause this behaviour. I hope someone can point me in the right direction, I feel like I’m close to the answer but I can’t get it right.

Thank you all for your time.

EDIT: Relevant error message in the server:

*“View ID AllocatedID: 0 not found during lookup. Strange behaviour may occur.”

“Couldn’t invoke RPC function ‘S_FillWeaponLists’ because the networkView ‘AllocatedID: 0’ doesn’t exist”*

No errors present in the client, and prints confirm that the ID at the moment of the RPC being sent is 3, not 0 (So are the viewIDs of the networkviews in the objects in the scene).

EDIT 2: Some more general information.

Just before this first level is loaded, the level prefix is set.

Then, after loading, four gameobjects (Weapon Data among them) are instantiated from a prefab which already contains a networkview. The instantiation is not done with Network.Instantiate. These four objects contain scripts with DontDestroyOnLoad.

Then the networkviews get an allocated viewID. They get 1, 2, 3 and 4, both in client and server, no issues here. And when all of them are correctly allocated and assigned, then is when the above RPCs are called.

Have you read the networking documentation at http://docs.unity3d.com/Documentation/Components/NetworkReferenceGuide.html thoroughly? You either have to

a)use Network.Instantiate

b)have some way of assigning your NetworkViews a NetworkViewID manually and then make sure they have the same viewID and only one is the owner. (I’ve never tried to do this.)

I recommend using Network.Instantiate unless you absolutely need specific viewIDs. Network.Instantiate ensures all instantiated objects on all machines are synced. The computer calling Network.Instantiate becomes the owner of that GameObject.

As for your question about NetworkView ownership; only the owner can send state updates to the other, non-owner NetworkViews. These are not the same as RPC. RPC methods are used with the [RPC] tag and Network.SendRPC() in C#, while state updates are sent and read in OnNetworkSerialize() 15 times each second by default. State updates are also done for only the observed Component (Transform by default) of the NetworkView.

Also worth noting is that NetworkViews that are already in the scene when it is loaded get synced automatically.