问题描述
因此,我了解到[command]不适用于非玩家对象,但是...为什么?我应该如何同步非玩家对象(例如NPC位置)的数据.在非玩家对象上调用Command的功能可以节省每个客户端大量的重复计算时间.
So I understand that [command] does not work on non-player objects, however ...why? how am I supposed to sync data of non-player objects, such as NPC locations. The ability to call Command on non-player objects would save a lot of repeated computation time on each client.
有人对这个设计决定提出解决方法吗?
Has anyone come up with a workaround to this design decision?
此外,如果未同时在播放器对象上显示SyncVars,则似乎无法同步.
Also, it seems that SyncVars aren't being synced if not on player objects as-well.
现在我最好的策略是在播放器对象上存储大量数据,并且必须不断从外部类对其进行引用
Right now my best strategy is to store a whoooole lot of data on the player objects and have to keep making references to it from outer classes
抱歉,我指出了SyncVars仅在服务器上更新时才对非玩家对象起作用的情况
OOps my mistake, as pointed out SyncVars are working on non-player objects, just only when updated on the server
推荐答案
是的, [Command] 用于将播放器RPC发送到服务器.
Yes, [Command] is for sending player RPC's to server.
但是, SyncVars 会将具有 NetworkBehaviour (不仅仅是播放器对象)的任何对象上的状态从服务器同步到客户端.
However, SyncVars will sync the state from server to client on any object with a NetworkBehaviour (not just a player object).
权威的服务器方法是让服务器使用NetworkServer.Spawn()
生成NPC位置,然后更新NPC Syncvars ,它们会在所有客户端上自动更新.
The authoritative server approach is to have the server spawn your NPC locations with NetworkServer.Spawn()
and then update the NPC Syncvars, and they automatically will update on all clients.
如果您确实需要从客户端发送 [Command] ,则使用新版本的Unity,您可以使用AssignClientAuthority()
:
If you really need to send a [Command] from a client, with new versions of Unity you can grant a scene object local player authority using AssignClientAuthority()
:
如果您具有PRO许可证并且可以访问Unity 5.2 beta版,则他们将其添加到5.2b1
If you have a PRO license and can access the Unity 5.2 beta builds then they added this in 5.2b1
[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 上的RemoveClientAuthority(NetworkConnection conn)
班级.请注意,只有一个客户端可以成为对象的权限 一个时间.在具有权限的客户端上,该功能 OnStartAuthority()
被调用,并且属性 hasAuthority 将是 真的.客户端拥有的对象集可在 新属性 NetworkConnection.clientOwnedObjects ,它是一组 NetworkInstanceIds .出现消息时,可以在服务器上使用此设置 收到以确保实际发送邮件的客户端 拥有对象.当客户端断开连接时,该功能 DestroyPlayersForConnection
现在会销毁该所有者拥有的所有对象 连接,而不仅仅是玩家对象.有它们的对象 设置为客户端的权限必须在其客户端中设置 LocalPlayerAuthority NetworkIdentity .以前只有玩家对象可以具有本地 授权,这意味着 NetworkTransform (以及其他 组件)只能用于控制单个播放器 客户端上连接的对象.通过这些更改,有可能 在客户端上有多个受本地控制的对象.
For setting the authority on objects after they are created, there are the new functions AssignClientAuthority(NetworkConnection conn)
and RemoveClientAuthority(NetworkConnection conn)
on the NetworkIdentity class. Note that only one client can be the authority for an object at a time. On the client that has authority, the function OnStartAuthority()
is called, and the property hasAuthority will be true. The set of objects that is owned by a client is available in the new property NetworkConnection.clientOwnedObjects which is a set of NetworkInstanceIds. This set can be used on the server when a message is received to ensure that the client that sent the message actually owns the object. When a client disconnects, the function DestroyPlayersForConnection
now destroys all the objects owned by that connection, not just the player object. Objects which have their authority set to a client must have LocalPlayerAuthority set in their NetworkIdentity. Previously only player objects could have local authority, which meant that the NetworkTransform (and other components) could only be used for controlling the single player object for a connection on a client. With these changes it is possible to have multiple objects on a client that are locally controlled.
这篇关于Unity UNET-在播放器对象外部调用[Command]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!