Buffering of Network.Instantiate()

Hi all,

I’m trying to have multiple networked players running around and all able to see each other and the player’s respective minimap icons. The players show up fine, but any existing players’ minimap icons don’t show up when a new client joins. I’m not sure why, since the call to instantiate the icon is nearly identical to the one used to instantiate the player (see code below). The docs for Network.Instantiate() don’t say so explicitly, but I read in the forums that it gets translated to a buffered RPC. When I run a client in the Game view, I get the following console error mesage:View ID AllocatedID: 2 not found during lookup. Strange behaviour may occur I read elsewhere on the forums that it shouldn’t happen using Network.Instantiate(). Can someone guide me in the right direction or explain what I’m doing that’s causing the instantiation to not be buffered? Thanks.

function CreatePlayer () {
	var myPlayer : Object = InitializePlayer();
	InitializePlayerCamera(myPlayer);
	var myIcon : Object = InitializeMinimapIcon(myPlayer);	
	InitializeToolbar(myPlayer);
	InitializeMinimapCamera(myPlayer, myIcon);
}

function InitializePlayer () : Object {
	//The player is instantiated on the network.
	return Network.Instantiate(playerPrefab, playerPrefab.transform.position, playerPrefab.transform.rotation, myGroup);
}

function InitializePlayerCamera ( myPlayer : Object ) : Object {
	//The player camera is instantiated locally, so use GameObject.Instantiate().
	var myCamera : Object = GameObject.Instantiate(cameraPrefab, cameraPrefab.transform.position, cameraPrefab.transform.rotation);
	myCamera.transform.parent = myPlayer.transform;
	var playerClickSelection : PointAndClickSelection = myPlayer.GetComponent(PointAndClickSelection);
	if (playerClickSelection  myCamera.camera) {
		playerClickSelection.SetCamera(myCamera.camera);
	}
	return myCamera;
}

function InitializeMinimapIcon ( myPlayer : Object ) : Object {
	//The minimap icon is instantiated on the network.
	var myIcon = Network.Instantiate(minimapIconPrefab, minimapIconPrefab.transform.position, minimapIconPrefab.transform.rotation, myGroup);
	var iconScript : NetworkMinimapIcon = myIcon.GetComponent(NetworkMinimapIcon);
	if (iconScript) {
		Debug.Log("Icon script found for player " + networkView.viewID.owner.ToString());
		iconScript.SetMinimapIconTarget(myPlayer.transform);
	}
	else {
		Debug.LogError("Minimap icon not properly initialized for player " + networkView.viewID.owner.ToString());
	}
	return myIcon;
}

function InitializeToolbar ( myPlayer : Object ) : Object {
	//The toolbar is intantiated locally.
	var myToolbar : Object = GameObject.Instantiate(toolbarPrefab, toolbarPrefab.transform.position, toolbarPrefab.transform.rotation);
	myToolbar.transform.parent = myPlayer.transform;
	myToolbar.name = "Toolbar";
	myToolbar.BroadcastMessage("SetPlayer", myPlayer, SendMessageOptions.DontRequireReceiver);
	return myToolbar;
}

function InitializeMinimapCamera ( myPlayer : Object, myIcon : Object ) : Object {
	var minimapCamera : Object = GameObject.Instantiate(minimapCameraPrefab);
	var minimapCameraScript : MinimapCamera = minimapCamera.GetComponent(MinimapCamera);
	minimapCameraScript.SetTarget(myIcon.transform);
	if (minimapCamera.camera) {
		var playerToolbar : PlayerToolbarScript = myPlayer.GetComponentInChildren(PlayerToolbarScript);
		playerToolbar.minimapCamera = minimapCamera.camera;
	}
	return minimapCamera;
}

I’m bumping this because I’m having a similar problem.

I do a lot of streaming so my Network.Instantiate isn’t as simple as just running in OnPlayerConnected or whatever. When my host and all clients are loaded up, I tell all connected players (including the local host one) to create their characters. They are then created using Network.Instantiate. This works fine.

However, later when a player connects during the game, they load up and then when ready, are told to create their character. The character the new player creates using Network.Instantiate works correctly and appears on all other clients and the host, but none of the other characters (those created with earlier Network.Instantiate calls) appear.

Going through the logs, I do no see any errors that suggests the RPC is lost, or sent too early (before the asset is loaded and available) or whatever. It just appears that the supposedly buffered call is just not sent/received.

What’s the dealio?

I found out that the problem in my specific instance was that RPCs are not tied to a specific level. In my case, the OnPlayerConnect() function from the title screen scene was making a call to load the game level. Unfortunately, the player instantiation RPCs were getting fired on the newly connected client before the level loaded and were then being immediately destroyed. The workaround I’m using now is to simply state that those objects shouldn’t be destroyed on level load and then manually destroying them when I need to, but we’re looking into other methods (namely, not using Network.Instantiate() and manually buffering received RPCs until the proper level loads).

FFS, it looks like it was the same for me. Despite a whole lot of disabling sending and turning off the queue and some other stuff to try and prevent pre-load RPCs from going out. Eesh.

In any case, thanks for the tip. It does appear that Network.Instantiate/DontDestroyOnLoad/Network.Destroy is the (un)holy trinity.

I actually just today found this page in the docs that describes how to “turn off the faucet,” so to speak, on the RPC queue. It worked wonders for me.