Unet 同步动画图层权重 Unity 3D
Unet Syncing animator layer weight Unity 3D
我目前正在研究多人 fps 以学习 UNET 和 Unity。在这个项目中,我使用 Network Animator Component 来同步我的动画。
我有一层运行正常状态,如行走和跳跃,另一层仅控制上半身以进行范围界定。该层在确定范围时被激活。
参数同步正常但层权重不同步。
控制图层权重的脚本在远程播放器上被禁用,因为它是负责拍摄的同一脚本的一部分,我们不想从远程播放器拍摄。
所以我将该代码放在不同的脚本上并将 Layerweight 设为 Syncvar,但仍然没有结果。
这是设置权重并将其淡出的片段。
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 的文档和手册,但由于我很难理解这些调用的区别,所以很难完成这项相对简单的任务。
总的来说,[SyncVar]
的主要问题是它们
synchronized from the server to clients
所以不是反过来!
然后
[Command]
是一种 被任何客户端 调用但仅在 服务器上执行
的方法
[ClientRpc]
有点相反,它是由服务器调用,然后在所有客户端
所以我要做的是为图层权重设置一个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
布尔值并直接在调用客户端上分配值:
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;
}
我目前正在研究多人 fps 以学习 UNET 和 Unity。在这个项目中,我使用 Network Animator Component 来同步我的动画。
我有一层运行正常状态,如行走和跳跃,另一层仅控制上半身以进行范围界定。该层在确定范围时被激活。
参数同步正常但层权重不同步。 控制图层权重的脚本在远程播放器上被禁用,因为它是负责拍摄的同一脚本的一部分,我们不想从远程播放器拍摄。 所以我将该代码放在不同的脚本上并将 Layerweight 设为 Syncvar,但仍然没有结果。
这是设置权重并将其淡出的片段。
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 的文档和手册,但由于我很难理解这些调用的区别,所以很难完成这项相对简单的任务。
总的来说,[SyncVar]
的主要问题是它们
synchronized from the server to clients
所以不是反过来!
然后
[Command]
是一种 被任何客户端 调用但仅在 服务器上执行
[ClientRpc]
有点相反,它是由服务器调用,然后在所有客户端
所以我要做的是为图层权重设置一个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
布尔值并直接在调用客户端上分配值:
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;
}