c# - Unity 网络就绪检查

标签 c# unity3d 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);
             }
         }

     }
 }

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

最佳答案

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

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

        return true;
    }
}

您也可以使用 Linq 来缩短

using System.Linq;

...

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

然后像这样使用它

public void OnClickHeroButton()
 {
     HeroSelect();

     if (!PhotonNetwork.IsMasterClient) return;

     if(!AllPlayersReady)
     {
         return;
     }


     PhotonNetwork.LoadLevel(3);
 }

这仍然可以增强,因为现在主人必须反复按下,直到每个人都准备好为止。我还会使用 Coroutine喜欢

public void OnClickHeroButton()
{
     HeroSelect();

     if (!PhotonNetwork.IsMasterClient) return;

     StartCoroutine (WaitAllReady ());   
 }

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

     PhotonNetwork.LoadLevel(3);
 }

感谢 Iggy:

您可以使用 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);
}

注意:在智能手机上打字,但我希望思路清晰

关于c# - Unity 网络就绪检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59501359/

相关文章:

c# - 找不到命名空间并且无法添加引用

c# - 我可以切换到 64 位吗

c# - DoTween repeatType.yoyo 在 Sequence 中不起作用

c# - 错误: "RPC method not found" on method that was never called

c# - 自动将实体传递给 Controller ​​操作

c# - 将 DataGrid 转换为 DataTable

ios - iOS 构建中未显示 Unity 调试日志

c# - 我们可以在 C# 中使用 Struct 作为引用类型吗?

使用 Photon 的 R Shiny 独立应用程序

unity-game-engine - 如何将 "com.unity.Mono.nuget.mono-cecil"包安装到Unity项目中