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

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 actually managed to work out an authoritative server method and have created a tutorial on it: