2

所以我知道 [command] 不适用于非玩家对象,但是......为什么?我应该如何同步非玩家对象的数据,例如 NPC 位置。在非玩家对象上调用 Command 的能力将在每个客户端上节省大量重复计算时间。

有没有人想出解决这个设计决定的方法?

此外,如果不在播放器对象上,SyncVars 似乎也没有被同步。

现在我最好的策略是在播放器对象上存储大量数据,并且必须继续从外部类中引用它

编辑:OOps 我的错误,正如所指出的 SyncVars 正在处理非玩家对象,仅在服务器上更新时

4

1 回答 1

5

是的,[Command]用于将播放器 RPC 发送到服务器。

但是,SyncVars将在任何具有NetworkBehaviour的对象(不仅仅是播放器对象)上将状态从服务器同步到客户端。

权威的服务器方法是让服务器生成你的 NPC 位置,NetworkServer.Spawn()然后更新 NPC Syncvars,它们会自动在所有客户端上更新。

如果您确实需要从客户端发送[Command],使用新版本的 Unity,您可以使用以下方式授予场景对象本地玩家权限AssignClientAuthority()

如果您有 PRO 许可证并且可以访问 Unity 5.2 beta 版本,那么他们在 5.2b1 中添加了这个

网络:添加了对非玩家对象的客户端权限的支持。新功能 NetworkServer.SpawnWithClientAuthority(GameObject obj, NetworkConnection conn)允许在创建对象时通过其连接将权限分配给客户端。这通常用于请求生成对象的客户端的命令处理程序中,然后将传入客户端的连接。例如:

[Command] 
void CmdSpawn() { 
    var go = (GameObject)Instantiate(otherPrefab,
    transform.position + new Vector3(0,1,0), Quaternion.identity);
    NetworkServer.SpawnWithClientAuthority(go, base.connectionToClient); 
}

在创建对象后设置对象的权限,有新函数AssignClientAuthority(NetworkConnection conn)NetworkIdentity 类。请注意,一次只能有一个客户授权一个对象。在具有权限的客户端上, 调用该函数,并且属性hasAuthority将为真。客户端拥有的对象集在新属性NetworkConnection.clientOwnedObjects中可用,该属性是一组 NetworkInstanceIds。当接收到消息时,可以在服务器上使用此集合,以确保发送消息的客户端实际拥有该对象。当客户端断开连接时,函数 RemoveClientAuthority(NetworkConnection conn)OnStartAuthority()DestroyPlayersForConnection现在销毁该连接拥有的所有对象,而不仅仅是玩家对象。将其权限设置为客户端的对象必须在其 NetworkIdentity中设置LocalPlayerAuthority。以前只有玩家对象可以拥有本地权限,这意味着NetworkTransform(和其他组件)只能用于控制客户端连接的单个玩家对象。通过这些更改,可以在客户端上拥有多个本地控制的对象。

于 2015-07-28T02:03:37.290 回答