Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Photon Unity Joining a room with game in progress

Discussion in 'Connected Games' started by ThySpektre, Oct 3, 2018.

  1. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    I would like to join a room via a lobby scene and have a correct unique player index before transitioning into the next scene (which may or may not be in progress) such that objects may be instantiated in that scene correctly.

    Is Photon capable of this? I've tried multiple methods such as Photon's included player indexing utility and trying to set player properties in the lobby before moving on, but all have run into timing problems.
     
  2. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    2,025
    Each client that connects to a Photon room gets an ActorNumber. This is instant, when joining the room, so that number is very reliable and won't repeat.
    On top of this, PUN has a player indexing component which figures out a player number between 1 and MaxPlayers. Example: You have 4 players in a room already and the player with ActorNumber 1 leaves. The remaining players keep their ActorNumber each and their player index, too. A new client may join and gets a new, higher ActorNumber from the server, e.g. 5. The player index should be 1 in this case, as that number became available when the ActorNumber 1 left.

    If this is not working for you, let us know how it's wrong. We can have a look.
    In PUN 2, we cleaned this up some more and the component you should have in the scene for this is: PlayerNumbering. Have a look at it's doc in-code or in the .chm file.

    As for lobby: Only when you are in a room, you can communicate with everyone else in that room. If you enter a room and others are in another scene, you will run into issues where a client gets updates from networked objects, which the local client didn't load yet. This causes issues, so it might be easier to load the correct scene but show a UI on top of that (or a different camera or whatever). Fake it :)
     
  3. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    Unfortunately, I don't see anyway to convert this to an index.

    Yes. This component does NOT work reliably. The issue is detailed well here.

    https://forum.photonengine.com/disc...ifferent-scene-with-autosyncscene-true#latest

    I have, as detailed in the above post. I need a method by which players can have a unique ID BEFORE entering the scene. If AutoSyncScene is enabled, this does not occur. If AutoSync Scene is not enabled this problem exists...

     
    Last edited: Oct 10, 2018
  4. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    2,025
    The PhotonPlayer.ID is a unique ID (in a room), given by the server when someone joins a room. In PUN 2, this is the Player.ActorNumber. It's never reused and automatically used all messages.
    The player numbering / indexing does not provide a unique ID: When player number 2 leaves (e.g.) someone else may become player 2, joining a moment later.
    This is why you should use the player numbering in a purely cosmetic way (display, etc) and instead rely on the PhotonPlayer.ID for anything that identifies a client/actor in the room.
    Player Numbering needs some negotiation, which is why it's not always available on join.
    We could make everyone wait until it's done, of course but this wasn't requested often, before.

    So, if you want to build your logic based on non-unique numbers which are reused when players leave and others join, then you should simply do your own level loading and when the player numbering for new players is "done", you load the new scene (leaving the "lobby scene"). Deactivate PUN's "Automatically Sync Scene" feature, put the "map" info into a Custom Room Property and use that to load the play scene whenever you're ready.

    In PUN 2, the Asteroids Demo is doing something like it: It has a screen where every player has to check "ready", before we start the game. This is similar. You can do this in PUN Classic, too, of course.

    Edit: PhotonViews do relate to the Player.ID, not the player number. Updates, RPCs and all that are related to the .ID and not to the number (which is, as said, reused). So it really makes sense to just sort your display based on the player number...
     
  5. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    Thanks Tobiass. That sentence was worded badly. An index is unique at any point in time. That is what I am looking for. Startup behaviors of the various players depend on the index of the player in game. There are a finite number of behaviors. These are mapped to the players' indicies. As such, PhotonPlayer.ID is not suitable.

    Unfortunately, this runs into the same timing issue detailed previously. Converting these ID's into indicies requires communication with the room.

    I'm not sure I understand this. If you are joining a game in progress (as is the problem case here) the other players would continue playing until the joining player had an index and could properly join the scene.

    How would one accomplish this? If one turns off the message queue these indicies never are communicated. If one turns on the message queue, one receives many messages for objects that do not yet exist.

    Are you saying each players' index should be stored as a custom room property as opposed to a custom player property?
     
    Last edited: Oct 11, 2018
  6. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    2,025
    That's my bad wording, sorry. :)
    I meant to say: We could delay the "joined" callback until the player number was "found". This will make "everyone" wait in the sense that it delays the joined callback for each player (individually, not for the full room).

    Both is doable. If you place this in the room properties, you may have some "assignments", which are outdated (when someone leaves). If a player has this in the player custom properties, then the entry gets cleared, when said player leaves.

    I would love to understand this better. Can I imagine this as .. assigning a role or something to players, depending on their placing in a team or .. comparable? Mail us, if you'd like to keep this out of public.

    I would probably try to load the correct scene in addition to the current one, which you keep as an overlay until everything is setup. The benefit would be that you could already make use of updates coming in the background but you'd not see it. Then, an event "im done / ready" might tell the others when the new player is ready.

    Technically, it should also be possible for everyone to calculate the correct player numbering with the values available on join: The player-list is known, their custom properties and their IDs. Even if more than one spot is vacant it's clear how new players pick spots (lowest first). So in theory, we don't need to wait until someone else made a choice and stored it. The results are clear. We just wait to double check.
    If the scene loading in the background doesn't work, we should take a look at this.
     
  7. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    Understood. This delay would certainly be helpful in my case. If I envision this timing correctly then, I could initialize AutoSyncScene and isMessageQueueRunning to false, wait for OnJoinedRoom() to fire and then enable these, knowing that when it sends me to the game scene, I'd have a valid player index.

    Understood, which is why I am currently implementing this via Player Properties. I had hoped that perhaps some Room Properties could be read before entering a room and thus avoid the timing issue.

    Yes, you understand it exactly right. Different team members have different behaviors that occur upon entering the scene. No amount of "hand waving" will alter their need to be correctly indexed prior to entering the game scene. (Including camera positioning, scene overlays, etc.) They must be properly indexed BEFORE entering the scene. (Thus the lobby scene)

    This is what I am doing currently. In the lobby scene, OnJoinedRoom() attempts to assign a player index. This works well most of the time, but falls if 2 or more players join in close proximity to one another. Here is the snippet from OnJoinedRoom()

    Code (CSharp):
    1.         //Setup Player Index
    2.         //Initialize Player Custom Property
    3.         Hashtable indexProps = new Hashtable() { { "in", -1 } };
    4.         //PhotonNetwork.player.SetCustomProperties(indexProps);
    5.  
    6.         //Iterate through all Players to get their index
    7.         bool[] taken = { false, false, false, false, false, false };
    8.  
    9.         foreach (PhotonPlayer photonPlayer in PhotonNetwork.otherPlayers)
    10.         {
    11.             int index = 0;
    12.             Nullable<int> nullIndex = photonPlayer.CustomProperties["in"] as Nullable<int>;
    13.             if (nullIndex != null)
    14.             {
    15.                 index = (int)nullIndex;
    16.                 taken[index] = true;
    17.                 print(index.ToString());
    18.                 if (index > -1)
    19.                 {
    20.                     taken[index] = true;
    21.                 }
    22.             }
    23.             else
    24.             {
    25.                 print("Null found.  Join time too close to another.  Duplicate Behavior will appear.");
    26.             }
    27.  
    28.         }
    29.  
    30.         //Step through indices until empty spot is found and assign it to player
    31.         int i2 = 0;
    32.         while (taken[i2] == true)
    33.         {
    34.             i2++;
    35.         }
    36.  
    37.         indexProps = new Hashtable() { { "in", i2 } };
    38.         PhotonNetwork.player.SetCustomProperties(indexProps);
    39.         PlayerNetwork.Instance.Index = i2;
    40.         print(i2.ToString());
    41.  
    42.         PhotonNetwork.automaticallySyncScene = true;
    43.     }
     
    Last edited: Oct 12, 2018
  8. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    2,025
    It's weekend time here. I'm sorry but this delays a proper reply to Monday.
     
  9. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    You have weekends?!?!?!?

    Enjoy.
     
    tobiass likes this.
  10. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    2,025
    It would be impossible to get this safe. Before you're in the room, you are on the Master Server, which would need to get the info from the Game Server and it may change anytime. Then the client is in transition until being in the room.

    Ok. It would have been easier to solve, if the setup of a role is not needed when you're loading a scene but that's how things are now.

    I got it on my list to check this but couldn't find the time yet, as we're preparing PUN v2.3 with a few quite critical fixes.
    In general, I think it should be possible to cover all cases.

    How far are you atm?
     
  11. GamesBX2018

    GamesBX2018

    Joined:
    Oct 12, 2018
    Posts:
    1
    Thank you
    I have completed my work thanks to your sharing
    GamesBX
     
  12. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    Various components to the project are in different spots. We were hoping to stay with PUN v1.x for this game before moving to v2.x for the next, but we aren't to alpha testing yet.
     
  13. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    31
    Which work? Were you able to complete what I am tyng to do? If so, how?