- Home /
AllocateViewID over RPC but the NetworkView doesn't exist
Hello!
TL;DR: I set a NetworkViewID from server and tell all clients to create an object and set it's NetworkViewID to that, but this error occurs when a 2nd client joins (3 players). (Go and look at the picture and script below you lazy person)
I have been stuck on this error for a good few days now. I have a scene setup where I am running an authoritative server. When a client joins the servers game it requests a player to be made and in-turn, the server creates a NetworkViewID for it, and sends an unbuffered RPC to all clients (custom buffer when a new client joins to reduce overall buffer).
All clients then create a copy of the new client gameobject and set their networkview to the one created by the server (and passed through). This then allows all clients to have a copy of the server-set networview player gameobject whilst allowing the specific new client to adjust variables in their own copy (including the camera attached which is the reason it is set up this way).
The error occurs when the 2nd client (3rd player) joins the game (and onwards) and has the error for the NetworkVIewID that is allocated to the FIRST client to join the game (ID: 2).
My only thought is that the split second between the clients creating the new object and setting it's networkview, the game stores SOME data and feels it should be sending that to new clients.
@RPC // Called by the new client ONLY to RPCMode.Server
function spawnClientRequest(info : NetworkMessageInfo){ // recieves networkplayer from info.sender
var viewID : NetworkViewID = Network.AllocateViewID(); // create new id for new client
for(var clients in GetComponent(playersInGame).players.Keys){ // for all clients already made
networkView.RPC("spawnOldClients", info.sender, GetComponent(playersInGame).players[clients]);//make copies on new client
}
networkView.RPC("spawnClient", RPCMode.All, viewID, info.sender); // don't buffer, that way we reduce errors and lag from stored rpc's
}
@RPC
function spawnClient(viewID : NetworkViewID, asker : NetworkPlayer){ // Spawns client as requested
var made = Instantiate(playerPrefab, transform.position, transform.rotation); // Create the client's object on all
yield WaitForSeconds(1); // give it some time
if(made.GetComponent(NetworkView).networkView.viewID != viewID){ // set created object networkID to server-set one (giving server control)
made.GetComponent(NetworkView).networkView.viewID = viewID;
}
if(Network.isServer){ // Take control and store it's object and networkID in a dictionary
made.GetComponent(movement).enabled = true;
GetComponent(playersInGame).players[made] = viewID;
}
if(asker == Network.player){ // if this is the object WE asked for... allow me to watch the camera over shoulder
made.transform.Find("Camera").GetComponent(Camera).enabled = true;
made.transform.Find("Camera").GetComponent(AudioListener).enabled = true;
sceneCam.enabled = false;
}
}
@RPC
function spawnOldClients(viewID : NetworkViewID){
var made = Instantiate(playerPrefab, transform.position, transform.rotation);
yield WaitForSeconds(1);
if(made.GetComponent(NetworkView).networkView.viewID != viewID){
made.GetComponent(NetworkView).networkView.viewID = viewID;
}
}
Image available here: http://imgur.com/zH0aTUJ
One of the most tedious parts of this error is that it works fine with the first client, bun bot the second one.
Any help would be greatly appreciated, any other questions you have, feel free to ask!
Cheers,
Matt
Answer by 03gramat · Jan 15, 2015 at 02:20 PM
I actually managed to work out an authoritative server method and have created a tutorial on it:
Answer by Bunny83 · Jun 06, 2014 at 11:13 AM
Well, why do you yield for a second? You have to instantiate the object and assign the viewID ASAP or the next network update will cause errors.
I tried out removing the yield, I remember I tried it to fix a previous bug that is now irrelevant, however, removing the yield didn't change the result.
Thanks for the response though!