Continuing game once internet is disconnected and connected back again

I have implemented photon's Pun Solution for multiplayer in my Unity3d game and it is working fine except when I intentionally turn off my phone's data for few seconds and then turn it back on, the Player game object with PhotonView that I instantiated over the network destroys. Now I want a functionality where I can reconnect my player once internet connection is restored.
I am aware that using PhotonNetwork.ReconnectAndRejoin() connects the client to server back to server and then using PhotonNetwork.JoinRoom(LobbyController.RoomName) I can get connected back to the previous room. But the issue is how am I suppose to handle the player prefabs which were instantiated over the Photon network if I locally instantiate them then PhotonView has 0 as Id. Do I need to instantiate the Prefabs over the network again once internet connection is back? Please correct me if I misunderstood some functionality.
For checking internet I am using recursion, once internet is restored I reconnect and rejoin the room, I cached the room name.
public void CheckIfInternetIsBackOn()
{
    if (Application.internetReachability == NetworkReachability.NotReachable)
        Invoke("CheckIfInternetIsBackOn", 1);
    else
    {
        print("Reconnecting and rejoining");
        PhotonNetwork.ReconnectAndRejoin();
        PhotonNetwork.JoinRoom(LobbyController.RoomName);
    }
}

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @MehtaNitish,

    Thank you for choosing Photon!

    PhotonNetwork.ReconnectAndRejoin(); no need for PhotonNetwork.JoinRoom(LobbyController.RoomName);

    This requires the room to have PlayerTTL different than 0.

    I would not use Application.internetReachability.
    I don't think it's reliable enough, see other solutions on the internet.
    Also, I would wait for the client to be disconnected first before trying to reconnect.
    There is a PUN callback for that.
  • Hi @JohnTube,

    Thanks for your answer!!

    So, I don't need to call PhotonNetwork.ReconnectAndRejoin();, and for PhotonNetwork.JoinRoom(LobbyController.RoomName); I will have it called in a coroutine which will have it checked if the player is already disconnected or not, is that what you mean?

    For PlayerTTL and EmptyRoomTTL, I have set it to 120000 during the first time room is created
    RoomOptions roomOptions = new RoomOptions() { IsVisible = true, IsOpen = true, MaxPlayers = (byte)maxPlayersInARoom };

    roomOptions.PlayerTtl = 120000; // 120 sec
    roomOptions.EmptyRoomTtl = 120000;

    My main question is that once player is connected back to the room, which I am able to do, how do I have networked player instantiated for my client, as on disconnect both the network players are destroyed(I have 2 player game with Max number of players in a room set to 2). If I use the local instantiate on the Player prefab with PhotonView, the PhotonView's ID is zero and when I instantiate player over the network I can only instantiate one player. How should I approach this problem of instantiating the players back on successful connection? Or is there a way so that players are not destroyed instantaneously when internet connection is out rather wait for a small amount of given time?
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @MehtaNitish,

    PUN's own instantiation is "buffered", it makes use of events caching to resend the event and redo the instantiation for rejoiners or late joiners.
    Are you using manual instantiation?

    You could try creating rooms with roomOptions.CleanupCacheOnLeave = false; if you do not want to destroy networked objects on leave.

  • Hi @JohnTube

    Thanks for your inputs, I added roomOptions.CleanupCacheOnLeave = false; where room is being created, but see no difference. My networked player is still being destroyed. Below is the whole room code:
    RoomOptions roomOptions = new RoomOptions() { IsVisible = true, IsOpen = true, MaxPlayers = (byte)maxPlayersInARoom };

    roomOptions.PlayerTtl = 120000; // 120 sec
    roomOptions.EmptyRoomTtl = 120000;
    roomOptions.CleanupCacheOnLeave = false;

    Is there anything else I can do here?

    Regards,
    Nitish
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @MehtaNitish,

    Are you using PUN Classic?
    if so, there is also PhotonNetwork.autoCleanUpPlayerObjects which should be set to false.
  • Hi @JohnTube

    No, not PUN Classic. I am using Photon PUN 2, free one present on Unity Asset store.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @MehtaNitish,

    How do you instantiate networked objects in the first place?
    Do you use manual instantiation or you use PhotonNetwork.Instantiate?
  • Hi,

    it's also important to check the result of ReconnectAndRejoin: https://doc-api.photonengine.com/en/pun/v2/class_photon_1_1_pun_1_1_photon_network.html#ac5d45f11953217bf28e97b546f1d068b

    if false, then it's not going to work.

    I would try to Reconnect() first and then rejoin().

    Bye,

    Jean
  • Hi,

    Sorry for late reply, was busy in some other project.

    @JohnTube : I am using PhotonNetwork.Instantiate, below is the code snippet I am using
    GameObject player = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "Multiplayer_Piece"), Vector3.zero, Quaternion.identity);

    @jeanfabre : ReconnectAndRejoin() connects me back to the room, but now the issue is that my photon network game object is destroyed from the game. Do I need to instantiate that again manually? Is there mechanism so that when I am reconnected to the room my photon network game object instantiates back in the game with the previous properties?

    Thank you
  • Hi @jeanfabre,

    I called PhotonNetwork.Reconnect(); on successful recover of internet connection, then
    PhotonNetwork.RejoinRoom(LobbyController.RoomName);
    inside the OnConnectedToMaster() callback and received below two errors:

    PhotonView ID duplicate found: 1001. New: View 1001 on Multiplayer_Piece(Clone) old: View 1001 on Multiplayer_Piece(Clone) . Maybe one wasn't destroyed on scene load?! Check for 'DontDestroyOnLoad'. Destroying old entry, adding new.
    UnityEngine.Debug:LogError(Object)

    PhotonView ID duplicate found: 2001. New: View 2001 on Multiplayer_Piece(Clone) old: View 2001 on Multiplayer_Piece(Clone) . Maybe one wasn't destroyed on scene load?! Check for 'DontDestroyOnLoad'. Destroying old entry, adding new.
    UnityEngine.Debug:LogError(Object)

    Any idea how I can fix this?

    Thank you!
  • Dober23
    Dober23
    edited October 2019
    Same problem, bro. I trying to ReconnectAndRejoin().
     void CreatePlayer()
      {
        LocalPlayerGO = PhotonNetwork.Instantiate(this._playerPrefab.name, new Vector3(0f, 6f, 0f), Quaternion.identity, 0);
      }
    1) On disconnect with CleanupCacheOnLeave=false, old gameobject LocalPlayerGO with PhotonView, not destroyed instantly, and i got Error "PhotonView ID duplicate found". After some time old gameobject is destroyed, and new gameobject is autoinstantiated.

    2) On disconnect with CleanupCacheOnLeave=true, gameobject, instantiated with PhotonNetwork.Instantiate destroyed instantly. After reconnect new gameobject is autoinstantiated.

    Besides everything I think 2th point is more correct...

    1. Should I reassign old gameobject to new? And how?
    2. How i can recieve ref on new GameObject LocalPlayerGO, autoinstantiated after rejoin?

  • Hi,

    you can set your playerttl to a value in seconds for which your player will remain in "away" mode while you are disconnected and trying to reconnect.

    Bye,

    Jean
  • Hi @jeanfabre ,

    At create room I have set below values for room fields:
    roomOptions.PlayerTtl = 120000; // 120 sec
    roomOptions.EmptyRoomTtl = 120000;
    roomOptions.CleanupCacheOnLeave = false;

    Inside game OnDisconnected(callback received when internet connection is disconnected) I have called
    Invoke("CheckIfInternetIsBackOn", 1);

    the CheckIfInternetIsBackOn method is as below:
    public void CheckIfInternetIsBackOn()
    {
    if (Application.internetReachability == NetworkReachability.NotReachable)
    Invoke("CheckIfInternetIsBackOn", 1);
    else
    {
    print("Reconnecting");
    PhotonNetwork.Reconnect();
    }
    }

    Once reconnected I receive OnConnectedToMaster() callback and inside it I am rejoining the room like below:
    PhotonNetwork.RejoinRoom(LobbyController.RoomName);

    But this whole process is causing the new Network player objects instantiated without the track of which one is locally controlled and hence the data of previous player objects is lost.

    Is there a better way or some tweaks I can do in the above process, so that once internet connection is restored the player Network object's data is not lost(while it's not been more than 120 seconds as defined in PlayerTtl)?

    Thank you
  • Hi,

    I am not sure I fully understand "without the track of which one is locally controlled a"

    but, if your player was inactive, reconnecting will get him back all his custom properties, can we agree on that? do you see that or does his custom properties are null? Could it be that you are not referencing the actor ID and so really, you are joining the room as a new player instead as who you were previously?

    check this please, it uses rejoin, which should keep the actorId . https://forum.photonengine.com/discussion/10105/pun-reconnect-player-actorid

    Bye,

    Jean
  • Hi @jeanfabre ,

    Once the internet connection is established I call PhotonNetwork.Reconnect(); as described above, here the core problem is that the once reconnect() is called the Owner of the Photon View is not the ID it should be it says "Scene". I believe I am joining as a new player as you mentioned above. How should I reference the actor ID so I join room as previously connected player?

    Thanks,
    Nitish
  • Hi

    you set it to your local player first.

    have you tried reconnectAndRejoin() as well?]

    Bye,

    Jean
  • MehtaNitish
    edited October 2019
    Hi @jeanfabre ,

    Out of two players I have, one is set to be a local player at photon View component. Is there some where else also I need to set it as local player?

    When game starts I get Owner ID on both the Photon network game objects with Photon View component as shown in below image:
    https://ibb.co/g7XWPtC

    When connection is lost the Owner ID for both the network game objects (Multiplayer_Piece) as shown in below image:
    https://ibb.co/rkCbTpB

    And when I reconnectAndRejoin() on successful recover of internet connection I only get one photon network game object instantiated and for that one too the local controlled check box is not checked and receive the PhotonView ID duplicate found error as well , as show in below image:
    https://ibb.co/fNFVJcX

    Thanks
  • Hi,

    I think you are getting confused with several things.

    - there can be only one local player, you don't choose your local player, it's there always. You also don't set the localplayer of a photonView, unless you request ownership, which is not the case here I believe.

    you need to authenticate your players, are you doing that? you need to use PhotonNetwork.AuthValues for this. this is required if you want to reconnect.

    Bye,

    Jean