Onclick 我准备好按钮使用 Photon

Onclick I am Ready Button Using Photon

所以我目前正在开发一种方法,让当前房间中的玩家在等候室中进入或选择他们的特定物品。当每个玩家都完成了一个按钮被点击时 'I am Ready!'...当一个玩家点击我准备好了然后一个 Int 变量 ReadyPlayers 更新根据有多少人点击了我准备好按钮。如果 readyplayers (int) 匹配房间中的玩家数量,则开始倒计时。我面临的问题是配置自定义属性。我写了这段代码,希望它能解决这个问题,但我最终得到了逻辑错误,其中 readyplayers (int) 不计入玩家。

using Hashtable = ExitGames.Client.Photon.Hashtable;

//Variables
public int ReadyPlayers = 0;


//added this to the button on the inspector : onclick event
public void OnClickIamReady()
  {
    ReadyPlayers = (int)PhotonNetwork.LocalPlayer.CustomProperties["PlayerReady"];
    ReadyPlayers++;
    Hashtable hash = new Hashtable() { { "PlayerReady", ReadyPlayers } };
    PhotonNetwork.LocalPlayer.SetCustomProperties(hash);

    //when a player clicks this button deactivate it
    IamReadyButton.gameObject.SetActive(false);
    
    foreach (Player player in PhotonNetwork.PlayerList)
    {
      Debug.Log(player.NickName.ToString() + " " + " is Ready. " + " " + " Players Who are Ready : " + player.CustomProperties["PlayerReady"].ToString());

    }
  }

每个玩家都使用自己的自定义属性来存储他知道总共有多少准备就绪的玩家,这是没有意义的。

相反,您只想将自己设置为准备就绪。

然后确认大家准备就绪,开始比赛。 但是您不想对客户端本身进行此检查。网络延迟怎么办?如果两个客户端同时按下按钮,属性还没有同步怎么办?

-> 我宁愿只在 OnPlayerPropertiesUpdate

内检查主客户端

所以像

using System.Linq;

...

public void OnClickIamReady()
{
    // Do not use a new hashtable everytime but rather the existing
    // in order to not loose any other properties you might have later
    var hash = PhotonNetwork.LocalPlayer.CustomProperties;
    hash["Ready"] = true;   
    PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
    IamReadyButton.gameObject.SetActive(false);

    if(!PhotonNetwork.IsMasterClient) return;

    CheckAllPlayersReady ();
} 

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

     if(!changedProps.ContainsKey("Ready")) return;

    CheckAllPlayersReady();
}

public override void OnMasterClientSwitched(Player  newMasterClient)
{
    if(newMasterClient != PhotoNework.LocalPlayer) return;

    CheckAllPlayersReady ();
}   


private void CheckAllPlayersReady ()
{
    var players = PhotonNetwork.PlayerList;

    // This is just using a shorthand via Linq instead of having a loop with a counter
    // for checking whether all players in the list have the key "Ready" in their custom properties
    if(players.All(p => p.CustomProperties.ContainsKey("Ready") && (bool)p.CustomProperties["Ready"]))
    {
        Debug.Log("All players are ready!");
    }
}