Photon.Instantiate not refreshing for recently joined player

Options
Hi, I followed the marco polo tutorial , and I can just see 2, or 3 users playing at the same time with no problem.
But when I tried to do this exact thing with a couple of objects in another project, I can't seem to show them correctly.
The 1st players creates some objects.
The 2nd player creates some more objects (all prefabs in resource folder with a photon view, using Photon.Instantiate).

1st player can see bot 1st and 2nd player objects
2nd player can only see theirs.

Also: What I'm trying to do is make the master client control a couple of objects, and I want that every other person in the room sees them too.

Should I make sometihng like a room chat, age of empires style, and only start the game when 4 players are ready? or there is a way to update every player who enters in a room after everyone else is there?

Comments

  • Tobias
    Options
    If your other project is not showing the object, those might either miss the PhotonViews on the GameObjects you instantiate or you don't instantiate with PhotonNetwork.Instantiate?

    The master client can create objects PhotonNetwork.InstantiateSceneObject(). Those are controlled by the master client (even if the master client changes, due to one leaving)...

    There is a callback you can implement: OnPlayerJoined or similar. Check PhotonNetworkMessages enum for a list of callbacks we call. In it, check the count of players. If 4, call some RPC to start the game.
  • If your other project is not showing the object, those might either miss the PhotonViews on the GameObjects you instantiate or you don't instantiate with PhotonNetwork.Instantiate?

    I'm doing both, setting photon views and instantiating with PhotonNetwork.Instantiate
    The master client can create objects PhotonNetwork.InstantiateSceneObject(). Those are controlled by the master client (even if the master client changes, due to one leaving)...

    This might work, and I will have to do this too, but eventually I would have to do it the other way so in some point I'll have to fix this :D
    There is a callback you can implement: OnPlayerJoined or similar. Check PhotonNetworkMessages enum for a list of callbacks we call. In it, check the count of players. If 4, call some RPC to start the game.

    This is actually what I'm doing for turn based games to work around this issue ,so I'm glad I'm on the right track.

    So just to be clear, it is possible to give a new player the last state of the game?
    Also, I noticed, that if I added a lobby in another scene, and then load the tutorial, I can't see the master client, so I think this has something to do with loading a scene. Is there any way around this?

    Thanks for your help!
  • Tobias
    Options
    Most likely your later-joining client is getting the commands to create all objects, then loads a level which destroys the GOs instantly.
    If you load scenes, Unity will destroy all existing objects. The Photon server doesn't know about the scenes, so it neither tries to recreate things in the correct level nor does it mind if loading levels destroys things.

    Take a look at PhotonNetwork.LoadLevel. I think (hope?) it takes care of this by syncing the level every client has to load. It should pause execution of incoming events when it detects it needs to load a level. When that's done, it continues to execute and instantiate things.
    The PUN v1.22 package uses this in the Worker Demo.
  • Ok I'll take a look. Thanks!

    And about my last question.
    Let's say I'm building a counter strike like game, and in certain point, a user enters the room.
    Photon cloud doesn't have a way to build the entire scene for that player right? or I just cannot see it because I'm loading after entering a room?

    Maybe a better way is to make the lobby connect and then avoid loading a new scene, but level loading is really common for example in a counter strike game, so I think that will be undoable. Any ideas on how to sync everything? Or if it just can't be done..
    ( I'm asking this without having a look at the loadLevel example tho, but I'll just throw the question since I think is a different thing :D )
    Thx Tobias!
  • Yeah you were right Tobias, i just "hold up" the networking on the client while he is loading the scene, and bum! everything appears as soon as the scene is loaded ;)
    thx again for your help!

    In case someone needs it:
    I have a lobby in scene1, when some1 chooses a room and enters:

    public void OnJoinedRoom()
    {
    PhotonNetwork.isMessageQueueRunning = false;
    Application.LoadLevel(RoomScene);
    }

    I do this, then, when scene is loaded:

    void OnLevelWasLoaded(int level)
    {
    PhotonNetwork.isMessageQueueRunning = true;
    }

    so photon starts loading everything after that point.
  • Tobias
    Options
    Glad you could fix this!
  • hmmmm - I seem to be having this same issue, but the fix that worked for you doesnt seem to work for me.

    Players join into the room, then after a countdown, a new scene is loaded.

    To load that new scene I have the following code:

    PhotonNetwork.isMessageQueueRunning = false;
    PhotonNetwork.LoadLevel("TeamCompetitive");


    After that, when the new scene loads, I have a script that spawns the players into the game. In the Awake() function of that script I have:

    void Awake()
    {
    PhotonNetwork.isMessageQueueRunning = true;
    }

    Then I have:


    void OnLevelWasLoaded(int level)
    {
    if(level == 3)
    {
    PhotonNetwork.isMessageQueueRunning = true;
    PhotonNetwork.Instantiate("PlayerPrefab", spawnPoint.position, Quaternion.identity, 0);
    }
    }


    What happens is the player that joined the room first sees both players in the game. The second player only sees himself. Can anyone tell me what I might be doing wrong? Thanks.


    EDIT: When I run the unity editor and make that the second player to join the room, I get two warning messages upon loading up the new scene:

    1: OnDestroy for PhotonView View (0)1001 on PlayerPrefab(Clone) but GO is still in instantiatedObjects. instantiationId: 1001. Use PhotonNetwork.Destroy(). Loading new scene caused this. Identical with this: True PN.Destroyed called for this PV: True
    UnityEngine.Debug:LogWarning(Object)
    PhotonView:OnDestroy() (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/PhotonView.cs:210)


    2: Received OnSerialization for view ID 1001. We have no such PhotonView! Ignored this if you're leaving a room. State: Joined
    UnityEngine.Debug:LogWarning(Object)
    NetworkingPeer:OnSerializeRead(Hashtable, PhotonPlayer, Int32, Int16) (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:2965)
    NetworkingPeer:OnEvent(EventData) (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:1509)
    ExitGames.Client.Photon.PeerBase:DeserializeMessageAndCallback(Byte[])
    ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands()
    ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands()
    PhotonHandler:Update() (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/PhotonHandler.cs:76)


    It definitely seems like this player is somehow getting destroyed but I cant figure out why.
  • Tobias
    Options
    The player gets destroyed due to level loading. The first error is happening when you still have PVs at the time you load a new level. You could destroy them first or ignore the warning.

    The second warning is due to still receiving an update for something that got destroyed (no matter if by loading the level or by PhotonNetwork.Destroy()). It's a warning, which means: It could be an error or ok. By accident you could get an update for the previous level which you don't use anymore. In that case, it can be ignored.

    If you use LoadLevel, you don't have to turn on isMessageQueueRunning yourself. It takes care of that at the right time.
  • EDIT: OK this is interesting - I threw in a Co-Routine for the heck of it to wait 1 second after the scene loads before spawning the player and what do you know, its working now. I guess I was just instantiating too quickly even though the scene technically should have been loaded. Thanks!


    Hi Tobius and thanks for the reply.

    Ok so I am now deleting my PhotonView from the previous scene before loading the new scene. I also am just using PhotonNetwork.LoadLevel() and no longer using isMessageQueueRunning = false.

    Unfortunately, the second player that joins the game still cant see the first player already there. The first player can see both players. I am still receiving the warnings about GO still being in InstantiatedObjects and receiving OnSerialization for view ID 1001 but having no such PhotonView.

    You mentioned the error is from the player getting destroyed due to level loading. Is there something other than using PhotonNetwork.LoadLevel() that I should be doing to insure my player prefab is not destroyed? Anything else I could possibly be overlooking that is causing my second player to not see the first players prefab?

    I should also note that I dont actually instantiate the prefabs until the new scene loads, so I am a bit confused at how the scene loading is causing the troubles. Once the scene loads void OnLevelWasLoaded(), I call the PhotonNetwork.Instantiate then. But the new scene has already loaded at this point.

    Sorry for all the questions and I appreciate all the help!
  • Tobias
    Options
    The master client might have sent the first updates before the others could even start loading or loaded everything.
    Did the errors keep on happening or did they go away after a few log lines?
  • luxel
    Options
    I was so excited to see this post, because i was having exactly the same problem as Jojo.

    Even now, i'm still having problem with it, using PhotonNetwork.LoadLevel + PhotonNetwork.Instantiate (in the 2nd scene), the about 1 out of two tests, the 2nd client will see only himself, while the master client (1st client) sees both player objects. P.S. my master client was macbook, and 2nd client was android phone.

    And what I observed more is - When the problem happens, quickly, when the scene is being moved from scene1 to scene2, I can see the player object of the master client appearing. As soon as scene 2 is loaded, the player object disappears.

    Please help here...cause i'm stuck with this issue for a few days. (ideally, adding some latency before instantiating network object could work, but it's not the best solution)
  • Tobias
    Options
    Loading a scene will destroy all GameObjects of the other scene, unless they are explicitly marked as "dont destroy on load". This is a Unity feature.
    If a Master Client instantiates something first, then loads a level, the other players will do the same (in the same order) and lose the instantiated GO.

    You could load the level first or you could use "dontdestroyonload" or you can re-instantiate things after each level load (which is the worst idea, because each instantiate is still instantiated)...