[SOLVED] Changing scenes in a room

Options
Hi everyone,

I have recently started working with the Photon Cloud, PUN and Unity 4.2.0f4. Using the tutorials provided by Exit Games, I have been able to create a small prototype of the game my team and I want to make. Everything was working great until I recently tried to implement a small scene where the players had to wait for everyone to be ready to start the game. The problem here is, that the players are missing the master client's game object. Only the master itself can see his game object instance, the other players receive loads of warnings stating that they receive serialization for a missing PhotonView (namely the master client's view).

If I skip the small scene and load the main game scene right out of the lobby everything is working just fine.

Whenever a player presses the ready button I call a RPC and inform every other client about it for display reasons. The master client runs this additional piece of code every time he receives the specific RPC:
[code2=csharp]if(PhotonNetwork.isMasterClient && b_readyCounter == PhotonNetwork.room.playerCount)
{
PhotonNetwork.room.open = false;
PhotonNetwork.LoadLevel(str_GameSceneName);
}[/code2]
This triggers the scene change for every client.

I am clueless as to what I am doing wrong when changing the scene and I hope some of you can show me my error and explain it to me.

Best regards,
Korbinian Bergauer

Comments

  • Tobias
    Options
    I can't see how and where you instantiate the PhotonView that players are reported as missing.
    You could create a GameObject with a PhotonView in the scene. This way, all clients will load it when they go into the "getting ready" screen and none would miss it.
    This PV shouldn't observe a script or otherwise have updates to send.
    You could mark this GameObject as DontDestroyOnLoad and re-use it across scenes.
    Or you can give it a specific LevelPrefix, which is not used in your game-scene. This way, updates that still arrived after you triggered the load-scene (which destroys objects that are not flagged as "DontDestroyOnLoad") will be ignored.
  • Thanks for your quick reply!

    I have a player prefab that has all necessary components (like the PhotonView) which is instantiated by an object in the scene I want to load. On awake it calls PhotonNetwork.Instantiate and the player's instance is created.

    This is working for all players but the master client. The master client instantiates his object only on his client and as soon as he tries to serialize his view to all other clients, they throw a warning stating that the PhotonView sending messages to them is not assigned.

    EDIT:
    I know the problem now. The master client's object is being instantiated on the other clients before they were able to load the scene resulting in two null reference errors from GameObject.Find() and the abortion of the instantiation.
    Is there a way to delay the instantiation until the client has fully loaded the scene?
    Or can I load the scene while staying in another and switch it on all clients once they have all finished loading it?
  • Tobias
    Options
    You can pause executing incoming messages while you load. This is done via: PhotonNetwork.isMessageQueueRunning = false. Don't forget to enable this again once you loaded everything or else it looks like your client doesn't get any messages anymore.

    I think PhotonNetwork.LoadLevel() can also help you and will pause the queue as long as needed. Read the description for this method, as you also have to turn on auto-syncing the loaded level.
  • I set automaticallySyncScene to true on awake of the 'Ready' scene and all clients are properly loading the scene. I don't know how to disable the execution of incoming messages for the clients as the level change is triggered by the network, not myself. I checked the PhotonNetwork.LoadLevel method out and it does disable message execution itself once it's called, so that should cover it anyway.

    I will try disabling execution on awake of the game scene for all clients and enable it once the scene is loaded and see it that does the trick.

    EDIT:
    Manually disabling execution did not work and should not be necessary as PhotonNetwork.LoadLevel disables it anyway and the PhotonHandler enables it again in OnLevelWasLoaded using NetworkingPeer.NewSceneLoaded.

    EDIT:
    I fixed it!

    Instead of instantiating my player instance in the Awake method of a script I instantiate it in OnLevelWasLoaded. This way the other clients receive the message after they have loaded the scene themselves. I think the master client was sending his message before the other clients switched scenes and disabled their message execution (based on lots of debug logs I created to trace every single step made by my scripts and PUN).

    Thank you for your help Tobias, I really appreciate it!