LoadBalancingClient.cs is holding a reference to a target object that is no longer available

Background:

I have the "loading" scene, the "lobby" scene and the "game" scene in Unity (2021.3.8f1) and I'm using Photon PUN2. Loading scene works great and so does the redirect to the "lobby" scene (the first time). Lobby then also successfully redirects the player(s) to the "game" scene. No bugs whatsoever here.

The problem

Now here's where the fun starts - in the "game" scene, I added a button that allows players to return to the "lobby" scene when clicked - essentially to be able to leave the current room and go back to the lobby. I'm doing that by calling SceneManager.LoadScene("Lobby"); when "To Lobby" button in the "game" scene is clicked.

Now, when I do that, the lobby scene loads and I get the null reference exception in my:

public override void OnRoomListUpdate(List<RoomInfo> roomList) override method that's located in my CreateAndJoinRoomsSystem.cs script - the console says that the transform, that I use for displaying list of rooms in UI, is no longer available/got destroyed. At first I thought this is something related to the way unity handles (kills/clears however you want to call it) fields when loading a new scene /when switching between the scenes, but it's not!! I know that because I created, just for the test, the "ReferenceVarTestBetweenScenes.cs" script:

public class ReferenceVarTestBetweenScenes : MonoBehaviour

{

  [SerializeField] private Transform _roomsListRoot;


  private void Awake()

  {

    Debug.Log("_roomsListRoot je : " + _roomsListRoot);

  }

}

and attached it to the test game obj. in my "Lobby" scene, then I assigned the _roomsListRoot variable, run the game and indeed I was able to access its value every time I loaded the lobby scene.

Then I figured, the reason why that same transform is not available in the CreateAndJoinRoomsSystem.cs is because it inherits the MonoBehaviourPunCallbacks class !

The problem seems to be is in the LoadBalancingClient.cs =>

....

  public void OnRoomListUpdate(List<RoomInfo> roomList)

    {

      this.client.UpdateCallbackTargets();


      foreach (ILobbyCallbacks target in this)

      {

        target.OnRoomListUpdate(roomList); //HERE

      }

    }

....


here, the target, is not null, but the actual game object that it's referencing does not exist in the scene either!! So I went again into public override OnRoomListUpdate (..) in my CreateAndJoinRoomsSystem.cs script and when I tried to debug.log the following in OnRoomListUpdate :


.....

public override void OnRoomListUpdate(List<RoomInfo> roomList)

  {

    var availableRooms = roomList.Where

    (

      x => x.IsVisible &&

      x.IsOpen &&

      x.PlayerCount > 0 && x.PlayerCount < maxRoomSize

    ).ToList();


    Debug.Log("_roomsListRoot is : " + _roomsListRoot); //_roomsListRoot is null here

    Debug.Log("I'm in CreateAndJoinRoomsSystem script, this is the Game Object Id of the object that's running this: " + gameObject.GetInstanceID()); // MissingReferenceException exception is thrown here =>

........

[the_rest_of_the_logic_in_this_method_is_not_important]

..........


So essentially I would get the MissingReferenceException saying :

.... MissingReferenceException: The object of type 'CreateAndJoinRoomsSystem' has been destroyed but you are still trying to access it.

Your script should either check if it is null or you should not destroy the object....


BUT AGAIN, this is because, for some reason, when loading the lobby scene for the second time (or any time other then the initial one frankly) the loading balancing client (what I mentioned above) would call the OnRoomListUpdate on a "target" instance that actually does not refer to any game object in the scene! That's why I'm getting the missing ref. exception when debugging this in visual studio, because it references something that's not in the scene anymore... Why is that? Why does it work the first time I load the Lobby scene, but not the second , the third, or any other time when I load it in the game?

BEAR IN MIND, NOWEHERE IN MY CODE AM I destroying the CreateAndJoinRoomsSystem game object in the scene! That is, the game object that has CreateAndJoinRoomsSystem.cs attached is only destroyed when loading the new scene, given how unity works. But I'm not destroying it manually and also I can confirm it's present at all times in the lobby scene whenever I load it, but for some reason the PhotonHandler/LoadBalancingClient "doesn't have it". Why?


Spent hours and hours on this and can't figure it out. Got so desperate that the current workaround for this is, when "to lobby" button is clicked in the "game" scene, then I execute:

    System.Diagnostics.Process.Start(Application.dataPath.Replace("_Data", ".exe")); //new program

    Application.Quit(); //kill current process


which essentially restarts the whole .exe (and no, I couldn't achieve similar with scene reload, because I was getting the same error in that case as well! even tried manually calling the garbage collector, unloading the scene, unloading the "unused assets", and all that.. nothing worked...) This is the only solution that truly forces the "hard reset" of everything , so yeah, this is a critical bug/blocker at the moment.


What am I missing? I assume I'm lacking some knowledge on how objects that inherit MonoBehaviourPunCallbacks are being handled by the PUN when switching between scenes, but what exactly and why is it that everything works the first time I load the lobby, but not any other?