我们正在Unity上构建实时策略游戏,并尝试通过网络销毁服务器和客户端上的游戏对象。 当前,玩家可以始终销毁自己的对象,而服务器可以销毁所有对象。但是,当客户端尝试销毁服务器(或其他客户端)的对象时,它只会在此客户端上销毁。 (由于客户端既没有Authority也没有对象isLocalPlayer)
我们尝试了不同的方法:
这显然不起作用,因为它只能在本地销毁。
此操作失败,因为我们没有权限。
当我们尝试在服务器上销毁对象的命令失败时,也会失败。由于权限检查:
试图未经授权就发送对象命令。
我们尝试通过以下方式分配权限
GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
但收到错误消息:
只能在服务器上为生成的对象调用AssignClientAuthority。
由于第3点,尝试在命令中执行此操作将失败。
还有其他销毁游戏对象的可能性吗? 销毁游戏对象的方法是什么?
编辑:我们在运行时(通过命令)通过NetworkServer.SpawnWithClientAuthority
或NetworkServer.Spawn
产生了大多数对象
答案 0 :(得分:1)
尽管事实UNet is going to end很快(如Draco18s所述),到目前为止我还是会这样做:
向要通过网络销毁/识别的NetworkIdentity
添加GameObject
。
如果是预制件,请确保将其添加到NetworkManager
由于本地播放器对象始终具有对自身及其连接组件的权限,因此将[Command]
调用添加到本地播放器对象上的组件 (不在目标上) GameObjects),并使用NetworkServer.Destroy
例如像
public class NetworkObjectDestroyer : NetworkBehaviour
{
// Called by the Player
[Client]
public void TellServerToDestroyObject(GameObject obj)
{
CmdDestroyObject(obj);
}
// Executed only on the server
[Command]
private void CmdDestroyObject(GameObject obj)
{
// It is very unlikely but due to the network delay
// possisble that the other player also tries to
// destroy exactly the same object beofre the server
// can tell him that this object was already destroyed.
// So in that case just do nothing.
if(!obj) return;
NetworkServer.Destroy(obj);
}
}
提示:您还可以添加此选项,以便于访问,因为您确定只需要访问这些组件之一(即本地播放器之一)即可:
public static NetworkObjectDestroyer Instance;
private void Awake()
{
// skip if not the local player
if(!isLocalPlayer) return;
// set the static instance
Instance = this;
}
稍后,在您需要执行销毁操作的其他脚本中的某处,您可以执行以下操作
// that you would have to get somewhere if not anyway
// calling from a component of the local player object
GameObject playerObject;
// wherever you get your target object from
GameObject targetObject;
playerObject.GetComponent<NetworkObjectDestroyer>().TellServerToDestroyObject(targetObject);
如果您之前添加了静态实例,会更容易。比起您可以简单地使用
NetworkObjectDestroyer.Instance.TellServerToDestroyObject(targetObject);
无需先获取参考。
答案 1 :(得分:0)
如何使用(1)并将每个客户端设置为对自己的游戏对象具有权限?然后,您需要确保的是让服务器在发生特定事件时通知每个客户端。
Here是关于多人游戏的一个开放性问题,描述了它如何手动工作。通过让客户端监听服务器消息/ RPC。
答案 2 :(得分:0)
直接来自统一文档:
地方当局 本地权限(有时称为客户端权限)是指本地客户端对特定的联网GameObject具有权威控制权。这与默认状态相反,默认状态是服务器对网络游戏对象具有权威控制。
除了isLocalPlayer ****,您还可以选择使玩家GameObjects具有“本地权限”。这意味着,其所有者客户端上的玩家GameObject对其自身负责(或拥有权限)。这对于控制运动特别有用;这意味着每个客户端都有权控制自己的玩家GameObject的控制方式。
要在GameObject上启用本地玩家权限,请勾选“网络身份”组件 的本地玩家权限复选框。网络转换组件使用此“权限”设置,如果设置了此信息,则将移动信息从客户端发送到其他客户端。
请参阅有关NetworkIdentity的Scripting API参考文档 和localPlayerAuthority获取有关通过脚本实现本地播放器权限的信息。
您只需要进行一些设置,就可以了!