【问题标题】:Unet, how to sync a counter to check if all players are readyUnet,如何同步计数器以检查所有玩家是否准备好
【发布时间】:2018-09-19 22:09:01
【问题描述】:

我正在使用 Unet 制作多人轰炸机游戏。我正在尝试创建一个就绪检查,以便在其他人都准备好时开始游戏。

我尝试使用同步变量、命令和 Rpc 调用,但似乎没有任何工作正常。

以这种方式使用 Cmd 调用时(当玩家按下就绪按钮时调用)

[Command]
private void CmdIncreaseReady()
{
        IncreaseReady();
        RpcIncreaseReady();

}
[ClientRpc]
private void RpcIncreaseReady()
{
    IncreaseReady();
}
private void IncreaseReady() {

    playersReady++;
    //ChechAllReady();
}

在客户端按下时,每个人的计数器都是0(应该是1),在服务器上按下时,服务器的计数器是2,客户端是1。

我尝试在 !isServer 和 Rpc 时调用 Cmd,结果是在客户端上按下时仍然不更新,但它已正确更新(两者上的计数器均为 1),当在服务器上按下。

if (!isServer)
    {
        CmdIncreaseReady();
    }
    else
    {
        RpcIncreaseReady();
    }

如果我删除Cmd上的IncreaseReady()调用,结果和上面一样。

我也尝试使用[SyncVar] 到计数器,有和没有钩子,在钩子上传递 1(以增加计数器的数量)并传递已经增加的计数器并将变量设置为该数字,似乎没有任何效果。

我真的不知道如何让它工作了。有人可以帮助我吗?我真的很绝望。我到处找。

脚本是游戏管理器,当每个客户端都有自己的版本时,它有一个网络身份,并拥有本地玩家权限。

我尝试了另一种方法,在 Cmd 和 Rpc 上传递增加的数字,在函数内部,只需设置 playerReady = i。即使这样也行不通。

[更新]:

所以,我找到了我想要解决的具体问题,那就是同步非玩家对象的属性。 我尝试使用客户端权限生成游戏管理器,现在它似乎只在服务器上正确同步,客户端仍然不调用 Cmd 属性。

查看inspector中的Debug模式,我已经能够看到,在服务端,hasAutority为true,但在客户端为false。

这是我生成游戏管理器的播放器脚本上的代码片段:

 void Update()
{
    if (!sceneLoaded)
    {
        if(isServer & SceneManager.GetActiveScene().name == "Main Scene")
        //if (SceneManager.GetActiveScene().name == "Main Scene")
        {
            if (connectionToClient.isReady)
            {
                var go = (GameObject)Instantiate(gameManager);
                NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
                go.transform.SetParent(null);
                //go.GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
                globalManager = go.GetComponent<FSM>();

                //SetFSM();

                sceneLoaded = true;
            }

        }
    }

【问题讨论】:

  • 一些事情,尽管请参阅下面的答案。 “可能脚本必须附加到生成的玩家身上?” - 默认情况下是这样,除非您指定权限 - 请参阅标题“非玩家对象的客户端权限”docs.unity3d.com/Manual/UNetConcepts.html。这样做是为了鼓励将网络代码保持在一起,而不是到处乱七八糟。
  • YOur SYncVar 可能不起作用,因为当您添加 Hook 时,您必须手动设置局部变量。这样做是为了让您可以查看旧状态以防万一。 answers.unity.com/questions/1159005/…
  • 不要使用 !isServer - 它具有误导性。使用 isClient 和 isServer。当事情还没有产生时,你可能会困惑地看到你的客户评估 isClient == false
  • 是的,确实,似乎我正在尝试为非玩家对象设置客户端权限。我尝试使用权限生成游戏管理器,现在它可以工作了,但仅适用于服务器,不适用于客户端。
  • 好吧,很高兴你离你更近了一步。我认为您必须更新问题以匹配您现在遇到的确切问题以获得进一步的帮助,因为我不知道您的代码在哪里。 (:如果可以,请保持具体!

标签: unity3d networking multiplayer unity3d-unet


【解决方案1】:

UNET 有一个Lobby system,这正是我认为你想要的。它具有每个玩家的就绪状态,因此游戏会在所有玩家都准备好时开始。

我建议使用它,因为它可以让您不必重新实现退出、重新加入等操作...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 2015-10-20
    • 2018-03-12
    • 1970-01-01
    • 2016-02-01
    相关资源
    最近更新 更多