C# Photon Networking - Preventing duplicate GameObjects from spawning on Join.

This piece of code, currently spawns trees around my game - over the network, and assigns them to the scene.

This means, that any code attached to the trees, can interact with each other nice and easy, but also - they will not be deleted if the host or “master client” leaves the game.

[PunRPC]
public void spawnNetworkNormalTrees() {
    for (int t = 0; t < normalTreeSpawns.Length; t += 1) {
    	string TreeToSpawn = "Normal Tree";
    	PhotonNetwork.InstantiateSceneObject(TreeToSpawn, normalTreeSpawns[t], Quaternion.identity, 0, null);
    }
}

I am currently having a bit of difficulty however.

If a player leaves the game, and then rejoins the game - the rejoining client will reinstantiate trees. The game will then double up on trees, and will use the same ids, and it just begins to mess everything up.

Currently, the spawnNetworkNormalTrees() is being called by the following methods.

Network Manager:

void OnCreatedRoom() {
	created_room = true;
}

void OnJoinedRoom() {
	if (created_room == true && PhotonNetwork.isMasterClient == true) {
		worldController.spawnNormalTrees ();
	}
}

World Manager:

public void spawnNormalTrees() {
if (photonView.isMine) {
    	if (PhotonNetwork.isMasterClient) {
    	    	photonView.RPC ("spawnNetworkNormalTrees", PhotonTargets.All);
    	}
}
}

 [PunRPC]
 public void spawnNetworkNormalTrees() {
     for (int t = 0; t < normalTreeSpawns.Length; t += 1) {
         string TreeToSpawn = "Normal Tree";
         PhotonNetwork.InstantiateSceneObject(TreeToSpawn, normalTreeSpawns[t], Quaternion.identity, 0, null);
     }
 }

Hi,

This means, that any code attached to the trees, can interact with each other nice and easy, but also - they will not be deleted if the host or “master client” leaves the game.

This is a expected behaviour because you are using PhotonNetwork.InstantiateSceneObject(...) which is different to PhotonNetwork.Instantiate(...). When using PhotonNetwork.InstantiateSceneObject(...) these objects gets associated with the room instead of the client. Furthermore this means that the life time of those objects is linked to the room and they will exist as long as the room does (unless you destroy them earlier).

Additionally InstantiateSceneObject(...) can only be called by the MasterClient. With this knowledge you can furthermore optimize the RPC call of ‘spawnNetworkNormalTrees’ by using photonView.RPC("spawnNetworkNormalTrees", PhotonTargets.MasterClient);. And since you have a PhotonNetwork.isMasterClient condition before calling the RPC, you can maybe skip the whole RPC, because the MasterClient doesn’t need to send RPC for / to himself. I am not sure if you maybe messed up Instantiate and InstantiateSceneObject in this case or if maybe I don’t get what you want to achieve, so please let me know.

If a player leaves the game, and then rejoins the game - the rejoining client will reinstantiate trees.

According to your code snippets above that should not happen in this case. Additionally when ‘spawnNetworkNormalTrees()’ is called on a non-MasterClient, trying to instantiate scene objects should log some errors to the console because this is not allowed. So I guess that you have some unwanted RPC call somewhere in your code that forces the MasterClient to instantiate objects again. Please make sure, that there is no other RPC call and also check which client instantiates the latest objects.