unity3d – Unity:如何通过网络摧毁游戏对象?

我们正在Unity上构建一个实时战略游戏,试图通过网络摧毁服务器和客户端上的游戏对象.

目前,玩家总是可以销毁自己的对象,服务器可以销毁所有对象.但是当客户端试图销毁服务器(或其他客户端)的对象时,它只会在此客户端上被销毁. (因为客户既没有权威也没有对象是本地人)

我们试过不同的方法:

1.使用Destroy(gameObject)

这显然不会起作用,因为它只在本地销毁.

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.

尝试在命令中执行此操作将因Point 3而失败.

是否还有其他可能会破坏游戏对象?
破坏gameObjects的方法是什么?

编辑:我们通过NetworkServer.SpawnWithClientAuthority或NetworkServer.Spawn在运行时(在命令中)生成了大多数对象

最佳答案 尽管事实上
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);

无需先获得参考.

点赞