Search Unity

Third Party Photon: How to sync late-joining clients?

Discussion in 'Multiplayer' started by BrendanWhelan, Mar 19, 2019.

  1. BrendanWhelan

    BrendanWhelan

    Joined:
    Jan 18, 2019
    Posts:
    1
    Hey all, I've been messing around in PUN2 for a bit now, and I'm running into an issue I can't seem to wrap my head around. To boil it down to the main problem, players are able to pick items up and drop them elsewhere (or hold onto them), but when a new player joins the server and loads the scene, the objects are all in their original place. I want to avoid having a photonview on each of these items, as there could potentially be a very large number of them on the ground (renewable item drops). I'm currently handling the items by having an InteractableManager (Custom script on an empty gameobject) with a PhotonView that stores a list of all "items" in the scene, and when an item is picked up, it sends an RPC containing the items name and coordinates to all other clients to look for the item name in their list, and if the coordinates match, it destroys it. When an item is dropped/instantiated, I send an RPC to all clients telling them the name of the prefab and the coordinates to create it at. The clients all create their own instance of the item, and adds it to their InstanceManagers list. The system works for now (although a bit buggy) if players are already connected to the server. The issue arises when a new player joins the server after items have been picked up. For the new player, the scene is in it's original state, and any changes other players made are lost. I've tried searching for answers for a few days, and tested a few things (such as trying to figure out a way to send the InstanceManagers list over the network) and I'm just at a loss. I would really appreciate any help you can provide. Feel free to ask for further information if needed!

    TLDR: I can't figure out how to sync the game state to new players when they connect mid-session.

    A few solution I've tried:
    Saving all GameObjects in the scene into a file and then sending it and loading it. This seems to completely break Unity. The saving/loading works in a singleplayer game, but once PhotonViews are added they stop syncing upon the GameObject being recreated, even though the photon views still have the same viewID, and then unity freezes shortly after.

    Trying to sync the entire item list over OnPhotonSerializeView. Couldn't get it working due to GameObjects being unserializable? Not entirely sure.

    I've thought of a few other solutions, but they all sound very... bad, and slow lol. Like having the new client clear the scene, then sending each items name and coordinates in the master clients InstanceManager list one at a time and having the new client instantiate them in the same way they are dropped.
     
  2. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    460
    Hey,

    Not sure about PUN2 but PUN1 had an example scene where pick ups were implemented. It was a static class and the way it worked was that when a new player connected, the master client synchronized all of the items using RPCs. Though they were pickups, rather than something you could drop anywhere you liked.

    Couple of weeks ago I created a multiplayer drawing game. Which means players can draw lines anywhere in the world. The way it is networked is that everyone keeps track of all the drawings. I have a Dictionary<playerId, Dictionary<drawingId, DrawEntity>>. This dictionary contains the drawings of all of the players. When a drawing is added or removed, this dictionary is updated. When a new player joins, the master client starts synching all of these drawings to the new player in a co-routine. The co-routine consists of multiple for loops. So I am looping over all players and over all of the drawings of that certain player. I of course limit the amount of data I send with each RPC. Every drawing might consist of hundreds of parts (in your case, items). Instead of sending everything at once, I send around 50 parts with every RPC. Making sure that the amount of data stays under 1Kb per RPC. During synchronization I of course do checks if the player who had this drawing left or if the drawing was deleted by the owner during synching.
    The problem with this solution currently is that when the master client leaves mid-sync, the new master client will not continue synching. For this I would need to do additional checks and keep track of the synching progress itself. However, it was not needed in my game so I left it there.

    So, in your case, since the master client can leave any time, Every player should keep track of all the items (its id, position, rotation, who owns/carries it and other state information if there is any). When a new client joins, let the master client start synching all of the items (just use RPCs). Items which you believe should be synced as soon as possible, send first. Everything else can be sent later.

    Hope this helps a little bit.
     
  3. jordano00

    jordano00

    Joined:
    Jul 3, 2016
    Posts:
    10
    Hi Frosty,

    I am also working on a drawing game with multiplayer using PUN 2, would you mind sharing what you did for syncing drawings for late joining players?

    Thank you!