【问题标题】:Unet Syncing animator layer weight Unity 3DUnet 同步动画层权重 Unity 3D
【发布时间】:2020-06-17 09:30:42
【问题描述】:

我目前正在制作多人 fps 以学习 UNET 和 Unity。在这个项目中,我使用 Network Animator 组件来同步我的动画。
我有一层运行正常状态,如行走和跳跃,另一层只控制上半身的范围。该层在确定范围时被激活。

参数是同步的,但不是层权重。 控制层权重的脚本在远程播放器上被禁用,因为它是负责拍摄的同一脚本的一部分,我们不想从远程播放器进行拍摄。 所以我把那段代码放在了不同的脚本上,把 Layerweight 做成了 Syncvar,还是没有结果。

这是设置权重并将其淡出的 sn-p。

    if (isScoped)
    {
        animator.SetLayerWeight(1, 1);
        layerWeight = 1;
    }
    else
    {
        layerWeight = Mathf.Lerp(layerWeight, 0, 0.1f);
        animator.SetLayerWeight(1, layerWeight);
    }

    animator.SetBool("Scoped", isScoped);

如何同步在禁用脚本上更新的变量? 我应该使用哪些不同的自定义属性(如 [Command] 和 [ClientRpc] 来使其正常工作?
我已经阅读了 UNET 的文档和手册,但是在这个相对简单的任务中遇到了困难,因为我很难理解这些调用的区别。

【问题讨论】:

  • 你为什么不禁用整个脚本只通过标志禁用Shoot 方法呢? (if(!IsLocalAuthority) return;)

标签: unity3d synchronization unity3d-unet


【解决方案1】:

一般来说[SyncVar] 的主要问题是它们是

同步从服务器到客户端

所以不是反过来!


然后

[Command] 是一个由任何客户端调用但只在服务器上执行

的方法

[ClientRpc] 正好相反,它由服务器调用,然后在所有客户端

上执行

所以我要做的是为 layerweight 设置一个 setter 方法,比如

private void SetLayerWeight(float value)
{
    // only player with authority may do so
    if(!isLocalPlayer) return;

    // Tell the server to update the value
    CmdSetLayerWeight(value);
}

[Command]
private void CmdSetLayerWeight(float value)
{
    // Server may now tell it to all clients
    RpcSetLayerWeight(value);
}

[ClientRpc]
private void RpcSetLayerWeight(float value)
{
    // called on all clients including server
    layerweight = value;
    animator.SetLayerWeight(1, layerweight);
}

然后这样称呼它

if (isScoped)
{
    SetLayerWeight(1);
}
else
{
    SetLayerWeight(Mathf.Lerp(layerWeight, 0, 0.1f));
}

请注意,尽管在服务器和客户端之间来回传递它会导致一些不可思议的延迟!

您可能会更好地同步 isScoped bool 并直接在调用客户端上分配值:

private void SetScoped(bool value)
{
    // only player with authority may do so
    if(!isLocalPlayer) return;

    // for yourself already apply the value directly so you don't have
    // to wait until it comes back from the server
    scoped = value;

    // Tell the server to update the value and who you are
    CmdSetLayerWeight(value);
}

// Executed only on the server
[Command]
private void CmdSetLayerWeight(bool value)
{
    // Server may now tell it to all clients
    RpcSetLayerWeight(value);
}

// Executed on all clients
[ClientRpc]
private void RpcSetLayerWeight(bool value)
{
    // called on all clients including server
    // since setting a bool is not expensive it doesn't matter
    // if this is done again also on the client who originally initialized this
    scoped = value;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 2018-02-05
    • 2017-07-17
    相关资源
    最近更新 更多