Unity 联网就绪检查

jos*_*son 3 c# unity-game-engine photon

尝试使用 PUN2 创建就绪检查,以便所有玩家同时加载到游戏场景中,但我不明白如何检查其他玩家的自定义属性并记录当前有多少玩家准备好以及是否全部准备好准备好然后开始游戏。我认为我应该为每个玩家设置一个自定义属性,但我不确定它是否有效。

 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);
             }
         }

     }
 }
Run Code Online (Sandbox Code Playgroud)

目前发生的情况是,主客户端可以开始游戏,而不管其他人的状态如何。感觉我可能想得太多了,并且有一个非常相似的解决方案,因为我希望这样的功能很常见,因为我希望在许多在线游戏中使用类似的功能,所以如果我要完全错误请给我指出一个更合适的方向

der*_*ugo 5

不确切知道 Photon 是如何工作的,但我假设这些属性已经同步,据我了解,您只需要某种检查,例如

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

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用 Linq 来缩短它,例如

using System.Linq;

...

private bool AllPlayersReady => PhotonNetwork.PlayerList.All(player => player.CustomProperties["PlayerReady"] == true);
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它

public void OnClickHeroButton()
 {
     HeroSelect();

     if (!PhotonNetwork.IsMasterClient) return;

     if(!AllPlayersReady)
     {
         return;
     }


     PhotonNetwork.LoadLevel(3);
 }
Run Code Online (Sandbox Code Playgroud)

这仍然可以增强,因为现在主人必须反复按下,直到也许每个人都准备好。我还会使用像这样的协程

public void OnClickHeroButton()
{
     HeroSelect();

     if (!PhotonNetwork.IsMasterClient) return;

     StartCoroutine (WaitAllReady ());   
 }

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

     PhotonNetwork.LoadLevel(3);
 }
Run Code Online (Sandbox Code Playgroud)

感谢伊吉:

您可以使用检查每个帧的例程OnPlayerPropertiesUpdate来检查就绪状态

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);
}
Run Code Online (Sandbox Code Playgroud)

注意:在智能手机上输入,但我希望这个想法能清楚