- Home /
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.
$$anonymous$$ore testing reveals something strange. So far it was the Server that allocated the IDs for the four objects in the scene. However, if it's the Client that allocates them, it assigns them the values 50, 51, 52 and 1, which is already weird, and also apparently receives three state updates from the server through viewID 0, which of course doesn't exist in the scene, and AFTER the Client allocates those IDs. I don't understand what's wrong.
I read somewhere that the one who allocates the IDs for networkviews becomes the owner of those. Is that true? In that case, who should allocate them, the Server, or each Client, knowing that these are four "manager" gameobjects, they do global stuff?
Are you sure there's no other script in those gameobjects that could be overriding or messing the RPC calls? What you say happens when the client allocates the IDs. Sounds like there are a couple of RPCs being sent to the client in the background.
Each gameobject has its own script, so there should be nothing messing with the RPC calls. I don't understand either why the client receives those three lost states when it's him who allocates IDs. Any ideas out there?
Answer by Jamora · Jun 25, 2013 at 08:05 PM
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.
I did read all of the docs regarding networkviews, RPCs, etc... Right now I'm NOT using Network.Instantiate for a very simple reason, and it's that I'm using a 2d plugin that requires me to use a different instantiating method without using Unity's prefabs. That is why after I instantiate the objects on both Client and Server, the Server allocates the viewIDs and assigns them correctly (as explained here http://docs.unity3d.com/Documentation/ScriptReference/Network.AllocateViewID.html).
Thanks for the tips though :D
Just wanted to clarify: the server allocates and sends the viewIDs correctly (apparently), but of course the original problem is still there, when the client sends the RPC the server gives an error saying the viewID 0 does not exist, even though both networkviews have assigned the ID of 3.
Your answer
Follow this Question
Related Questions
Get RPC senders ID, or IP? 1 Answer
Joining a Running Server (Game) and Waiting for Game State Data. How? 1 Answer
How to manage viewIDs? 1 Answer
Networking RPC calls never sent to other clients 1 Answer
network.RPC behavior 1 Answer