Unity:如何通过网络销毁游戏对象?
Unity: How to destroy a gameobject through network?
我们正在 Unity 上构建一个实时战略游戏,并试图通过网络销毁服务器和客户端上的游戏对象。
目前玩家可以随时销毁自己的对象,而服务器可以销毁所有对象。但是,当客户端试图销毁服务器(或其他客户端)的对象时,它只会在该客户端上被销毁。 (因为客户端既没有 hasAuthority 也没有对象 isLocalPlayer)
我们尝试了不同的方法:
1。使用销毁(游戏对象)
这显然行不通,因为它只会在本地被销毁。
2。使用 NetworkServer.Destroy(gameObject)
由于我们没有权限,所以失败了。
3。使用命令销毁对象
当我们尝试在销毁对象的服务器上调用命令时,也失败了。由于权限检查:
Trying to send command for object without authority.
4。先分配权限
我们尝试通过以下方式分配权限
GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
但收到错误消息:
AssignClientAuthority can only be call on the server for spawned objects.
由于第 3 点,尝试在命令中执行此操作将失败。
还有其他方法可以销毁游戏对象吗?
销毁游戏对象的方法是什么?
编辑:我们在运行时(在命令中)通过 NetworkServer.SpawnWithClientAuthority
或 NetworkServer.Spawn
生成了大部分对象
如何使用 (1) 并设置每个客户端对自己的游戏对象拥有权限?那么您需要确保的是让服务器在特定事件时通知每个客户端。
Here 是一个关于多人游戏的更开放的问题,它描述了它如何手动工作。让客户端监听服务器 messages/RPCs.
尽管 UNet is going to end 很快(正如 Draco18s 已经提到的)到目前为止我会这样做:
将 NetworkIdentity
添加到 GameObject
您希望能够通过网络 destroy/identify。
如果您生成的是预制件,请确保将其添加到 NetworkManager
中的可生成预制件中
由于本地播放器对象始终对自身和附加到它的组件具有权限,因此添加 [Command]
对本地播放器对象上的组件的调用(不在目标游戏对象上)并使用 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);
无需先获取参考文献。
直接来自统一文档:
地方当局
本地权限(有时称为客户端权限)意味着本地客户端对特定的网络游戏对象具有权威控制权。这与默认状态形成对比,默认状态是服务器对网络游戏对象具有权威控制。
除了isLocalPlayer****,你还可以选择让player GameObjects拥有“local authority”。这意味着其所有者客户端上的玩家 GameObject 对其自身负责(或对其拥有权限)。这对于控制运动特别有用;这意味着每个客户端都有权决定如何控制他们自己的玩家游戏对象。
要在 GameObject 上启用本地玩家权限,请勾选 Network Identity 组件
的本地玩家权限复选框。 Network Transform 组件使用此“权限”设置,如果已设置,则将移动信息从客户端发送到其他客户端。
参见脚本API有关 NetworkIdentity 的参考文档
和 localPlayerAuthority 获取有关通过脚本实现本地玩家权限的信息。
你只需要设置一些东西就可以了!
我们正在 Unity 上构建一个实时战略游戏,并试图通过网络销毁服务器和客户端上的游戏对象。 目前玩家可以随时销毁自己的对象,而服务器可以销毁所有对象。但是,当客户端试图销毁服务器(或其他客户端)的对象时,它只会在该客户端上被销毁。 (因为客户端既没有 hasAuthority 也没有对象 isLocalPlayer)
我们尝试了不同的方法:
1。使用销毁(游戏对象)
这显然行不通,因为它只会在本地被销毁。
2。使用 NetworkServer.Destroy(gameObject)
由于我们没有权限,所以失败了。
3。使用命令销毁对象
当我们尝试在销毁对象的服务器上调用命令时,也失败了。由于权限检查:
Trying to send command for object without authority.
4。先分配权限
我们尝试通过以下方式分配权限
GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient);
但收到错误消息:
AssignClientAuthority can only be call on the server for spawned objects.
由于第 3 点,尝试在命令中执行此操作将失败。
还有其他方法可以销毁游戏对象吗? 销毁游戏对象的方法是什么?
编辑:我们在运行时(在命令中)通过 NetworkServer.SpawnWithClientAuthority
或 NetworkServer.Spawn
如何使用 (1) 并设置每个客户端对自己的游戏对象拥有权限?那么您需要确保的是让服务器在特定事件时通知每个客户端。
Here 是一个关于多人游戏的更开放的问题,它描述了它如何手动工作。让客户端监听服务器 messages/RPCs.
尽管 UNet is going to end 很快(正如 Draco18s 已经提到的)到目前为止我会这样做:
将
NetworkIdentity
添加到GameObject
您希望能够通过网络 destroy/identify。如果您生成的是预制件,请确保将其添加到
NetworkManager
中的可生成预制件中
由于本地播放器对象始终对自身和附加到它的组件具有权限,因此添加
[Command]
对本地播放器对象上的组件的调用(不在目标游戏对象上)并使用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);
无需先获取参考文献。
直接来自统一文档:
地方当局 本地权限(有时称为客户端权限)意味着本地客户端对特定的网络游戏对象具有权威控制权。这与默认状态形成对比,默认状态是服务器对网络游戏对象具有权威控制。
除了isLocalPlayer****,你还可以选择让player GameObjects拥有“local authority”。这意味着其所有者客户端上的玩家 GameObject 对其自身负责(或对其拥有权限)。这对于控制运动特别有用;这意味着每个客户端都有权决定如何控制他们自己的玩家游戏对象。
要在 GameObject 上启用本地玩家权限,请勾选 Network Identity 组件 的本地玩家权限复选框。 Network Transform 组件使用此“权限”设置,如果已设置,则将移动信息从客户端发送到其他客户端。
参见脚本API有关 NetworkIdentity 的参考文档 和 localPlayerAuthority 获取有关通过脚本实现本地玩家权限的信息。
你只需要设置一些东西就可以了!