Unity: 如何通过网络销毁一个游戏对象?

4
我们正在Unity上构建一个实时策略游戏,并尝试通过网络在服务器和客户端上销毁gameobjects。目前,玩家始终可以销毁自己的对象,而服务器可以销毁所有对象。但是,当客户端尝试销毁服务器(或其他客户端)的对象时,它只在该客户端上被销毁。(因为客户端既没有authority,也不是local player)
我们尝试了不同的方法:
1. 使用Destroy(gameObject)
这显然行不通,因为它只会在本地销毁。
2. 使用NetworkServer.Destroy(gameObject)
由于我们没有权限,这将失败。
3. 使用命令来销毁对象
我们尝试调用一个在其中销毁对象的服务器命令时,它失败了。由于权限检查:
"Trying to send command for object without authority."
4. 首先分配权限
我们尝试通过GetComponent().AssignClientAuthority(connectionToClient)来分配权限,但会收到错误消息:
"AssignClientAuthority can only be call on the server for spawned objects."
在命令中尝试这样做将由于第3点而失败。
还有其他销毁gameObjects的可能性吗?销毁gameObjects的正确方式是什么?
编辑:我们大部分对象都是在运行时(在Command中)通过NetworkServer.SpawnWithClientAuthority或NetworkServer.Spawn生成的。

你是否正在使用 NetworkServer.Spawn 来创建你想要删除的对象? - Ruzihm
1
告诉服务器销毁任何东西。实际上,这个问题是我不喜欢UNet的原因之一,也是Unity正在废弃它并重新开始的原因之一。 - Draco18s no longer trusts SE
1
@Draco18s Unity真的要废弃uNet吗? - Programmer
1
@程序员 是的。https://support.unity3d.com/hc/zh-cn/articles/360001252086-UNet-%E5%BA%9F%E5%BC%83-FAQ - Draco18s no longer trusts SE
2
不知道呢。我正在真正学习它的时候,它就被弃用了。对于楼主来说,我建议你使用 Photon。它已经存在很长一段时间了,我认为它不会很快消失。 - Programmer
3个回答

3

尽管如Draco18s所提到的那样,UNet即将停用,但迄今为止我已经完成了以下工作:

  1. Add a NetworkIdentity to the GameObject you want to be able to destroy/identify over the network.

  2. If it is a prefab you spawn make sure it is added to the spawnable prefabs in the NetworkManager

  3. Since the local player object always has the authority over itself and components attached to it add the [Command] call to a component on the local player object (not on the target GameObjects) and use NetworkServer.Destroy e.g. something like

    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);
        }
    }
    

    Hint: You also could add this for easier access since you are sure that you only need access to exactly one of those components (namely the one of your local player):

    public static NetworkObjectDestroyer Instance;
    
    private void Awake()
    {
        // skip if not the local player
        if(!isLocalPlayer) return;
    
        // set the static instance
        Instance = this;
    }
    
  4. Than later somewhere in your other script that needs to execute the destroy you do something like

    // 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);
    

    It is easier if you added the static Instance before. Than you can simply use

    NetworkObjectDestroyer.Instance.TellServerToDestroyObject(targetObject);
    

    without having to get the references first.


这并不是我们所期望的答案。但是通过另一个SyncVar,我们成功地实现了这种方法。 - hochreutenerl

0
使用(1)并为每个客户端设置其自己的游戏对象权限如何?然后你所需要确保的只是让服务器在特定事件发生时通知每个客户端。 此处有一个更加开放性的多人游戏问题,描述了如何通过让客户端监听服务器消息/ RPC 来实现。

0

直接从Unity文档中摘录:

本地权限 本地权限(有时称为客户端权限)意味着本地客户端对特定的网络化游戏对象具有授权控制。这与默认状态相反,即服务器对网络化游戏对象具有授权控制。

除了isLocalPlayer****之外,您还可以选择使玩家游戏对象具有“本地权限”。这意味着玩家游戏对象在其所有者的客户端上负责自己(或对自己拥有授权)。这对于控制移动特别有用;它意味着每个客户端都对其自己的玩家游戏对象如何被控制具有授权。

要在游戏对象上启用本地玩家权限,请选中Network Identity组件的Local Player Authority复选框。如果设置了此项,Network Transform组件将使用此“权限”设置,并将移动信息从客户端发送到其他客户端。

有关通过脚本实现本地玩家权限的信息,请参阅Scripting API Reference文档中的NetworkIdentity和localPlayerAuthority。

请在此处查看

您只需要设置一些东西,就可以开始了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接