Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity Networked Ready check

Trying to create a ready check using PUN2 so that all players will load into the game scene at the same time, but I do not understand how to check another players custom property and keep a count of how many players are currently ready and if all are ready then start the game. I think I have a custom property set up for every player that should be but I am unsure if it working at all.

 public class HeroSelectController : MonoBehaviour
 {
     [HideInInspector]
     public string selectedHero;

     private PhotonView PV;
     private bool PlayerReady = false;
     private ExitGames.Client.Photon.Hashtable _playerCustomProperties = new ExitGames.Client.Photon.Hashtable();

     private void Update()
     {
         Debug.Log("Player Ready = " + _playerCustomProperties["PlayerReady"]);
     }

     private void HeroSelect()
     {
         PlayerReady = true;    
         selectedHero = "PlayerTest";
         PhotonNetwork.SetPlayerCustomProperties(_playerCustomProperties);
         _playerCustomProperties["PlayerReady"] = PlayerReady;
     }

     public void OnClickHeroButton()
     {
         HeroSelect();

         if (PhotonNetwork.IsMasterClient)
         {
             foreach (var photonPlayer in PhotonNetwork.PlayerList)
             {
                 photonPlayer.CustomProperties["PlayerReady"] = true;
                 PhotonNetwork.LoadLevel(3);
             }
         }

     }
 }

What is currently happening is that the master client can start the game regardless of everyone else's state. Feel like I might be overthinking all of this and there is a much similar solution as I would expect a function like this to be common place as I would expect something similar to be used in many online games so if I am going about completely the wrong way please point me a more suitable direction

like image 431
joshua davidson Avatar asked Dec 09 '25 01:12

joshua davidson


1 Answers

Don't know exactly how Photon works but I assume these properties are already synchronized and as far as I understand you simply want some kind of a check like e.g.

private bool AllPlayersReady
{
    get
    {
        foreach (var photonPlayer in PhotonNetwork.PlayerList)
        {
            if(photonPlayer.CustomProperties["PlayerReady"] == false) return false;
        }

        return true;
    }
}

Which you could probably also shorten using Linq like

using System.Linq;

...

private bool AllPlayersReady => PhotonNetwork.PlayerList.All(player => player.CustomProperties["PlayerReady"] == true);

And then use it like

public void OnClickHeroButton()
 {
     HeroSelect();

     if (!PhotonNetwork.IsMasterClient) return;

     if(!AllPlayersReady)
     {
         return;
     }


     PhotonNetwork.LoadLevel(3);
 }

This can still be enhanced since now the master has to press repeatedly until maybe everyone is ready. I would additionally use a Coroutine like

public void OnClickHeroButton()
{
     HeroSelect();

     if (!PhotonNetwork.IsMasterClient) return;

     StartCoroutine (WaitAllReady ());   
 }

 private IEnumerator WaitAllReady()
 {
     yield return new WaitUntil (() => AllPlayersReady);

     PhotonNetwork.LoadLevel(3);
 }

Thanks to Iggy:

Instead of a routine which checks every frame you can use OnPlayerPropertiesUpdate in order to check for the ready state

void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
    if (!PhotonNetwork.IsMasterClient) return;

    // you can even limit the check to make it 
    // only if "PlayerReady" is among the changed properties
    if(!changedProps.Contains("PlayerReady")) return;

    if(!AllPlayersReady) return;

    PhotonNetwork.LoadLevel(3);
}

Note: Typed on smartphone but I hope the idea gets clear

like image 67
derHugo Avatar answered Dec 10 '25 14:12

derHugo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!