Why do I get "Operation LeaveRoom (254) not called because client is not connected or not ready yet"

Options
I've just completed the tutorial (overall pretty great, although I have to say it's a little weird that it just "ends" and doesn't at least do something like "Ok, now go to your launcher scene and let's run the whole thing!") and am now playing the game to test it all out. I'm getting the following error when a player is killed:
Operation LeaveRoom (254) not called because client is not connected or not ready yet

I scanned a couple other questions on the forum that got a similar error, and it seems like the reason for this is that a player is trying to leave a room but is not IN a room, and I'm not really sure how that would be. As far as I can tell I've followed the tutorial correctly line-for-line and didn't inject any of my own code. Has anyone experienced this and found a solution, or would anyone at Photon be able to help me identify if I missed something in the tutorial that would cause this? Definitely want to make sure I understand this concept before I start coding my own game...

Answers

  • tetripod
    Options
    Sorry, to be clear, this is the PUN2 tutorial and I'm in Unity.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @tetripod,

    Please provide the full error message and the full stack trace.
    Most likely this is due to clicking "Quit" or "Leave Room" button multiple times, first time it works fine, second time this error is thrown because the client is already Leaving or Left.
  • tetripod
    Options
    Hey @JohnTube , thanks for the quick response. Here's my stack trace:
    Operation LeaveRoom (254) not called because client is not connected or not ready yet, client state: Leaving
    UnityEngine.Debug:LogError(Object)
    Photon.Realtime.LoadBalancingClient:DebugReturn(DebugLevel, String) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:2551)
    Photon.Realtime.LoadBalancingClient:CheckIfOpCanBeSent(Byte, ServerConnection, String) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:2480)
    Photon.Realtime.LoadBalancingClient:OpLeaveRoom(Boolean, Boolean) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:1907)
    Photon.Pun.PhotonNetwork:LeaveRoom(Boolean) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:1951)
    GameManager:LeaveRoom() (at Assets/Scripts/GameManager.cs:82)
    PlayerManager:Update() (at Assets/Scripts/PlayerManager.cs:102)
    
    FWIW, I'll mention that when I fire the beam it drains health on both the shooter and the victim, even though the beam collider is outside the collider for the player character as per the direction of the tutorial. I don't see how that would cause the player to try to leave the room twice, but I'm definitely not an expert so I may be overlooking/misunderstanding something.
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited May 2021
    Options
    Hi @tetripod,

    So checked the code, the stack trace does not lie and your hint about draining own health is on point.
    So there are two different issues: the beams colliding with local player (source of beam). This should be fixed somehow. Not sure how to be honest (it's the weekend and I'm not the original author of the tutorial, I just helped porting it to PUN 2 and with the documentation and I know 'a bit' of PUN 2).
    The other issue: when the health is equal or lower than zero, LeaveRoom should be called once.

    One possible solution is to add a flag "leaving" when the first call to LeaveRoom is called...

    PlayerManager.cs:
    private bool leavingRoom;
    
            /// <summary>
            /// MonoBehaviour method called on GameObject by Unity on every frame.
            /// Process Inputs if local player.
            /// Show and hide the beams
            /// Watch for end of game, when local player health is 0.
            /// </summary>
            public void Update()
            {
                // we only process Inputs and check health if we are the local player
                if (photonView.IsMine)
                {
                    this.ProcessInputs();
    
                    if (this.Health <= 0f && !this.leavingRoom)
                    {
                        this.leavingRoom = GameManager.Instance.LeaveRoom();
                    }
                }
    
                if (this.beams != null && this.IsFiring != this.beams.activeInHierarchy)
                {
                    this.beams.SetActive(this.IsFiring);
                }
            }
    
            public override void OnLeftRoom()
            {
                this.leavingRoom = false;
            }
    

    GameManager.cs:
    public bool LeaveRoom()
    		{
    			return PhotonNetwork.LeaveRoom();
    		}
    
  • tetripod
    Options
    Gotcha, ok. I'm going to file this under "Note to self: Write airtight logic for player departure" and start coding my own game with it in mind. Thank you!