为什么 NetworkServer.Spawn() 需要 [Command] 而 NetworkServer.Destroy() 不需要?

Why do I need [Command] for NetworkServer.Spawn() , but not for NetworkServer.Destroy()?

我有这个来自我正在制作的多人射击游戏的脚本,我对 [Command] 属性的使用有疑问

这是代码:

[Command]
public void CmdShoot()
{
    //Creat the bullet
    GameObject Bullet = (GameObject)Instantiate(bulletPrefab, Barrle.transform.position, Barrle.transform.rotation);
    BulletController bc = Bullet.GetComponent<BulletController>();
    bc.SetOrigin(this.transform.name);
    NetworkServer.Spawn(Bullet);

    //Shoot the bullet
    Rigidbody rb = Bullet.GetComponent<Rigidbody>();
    rb.AddForce(cam.transform.forward * BulletForce, ForceMode.VelocityChange);
}


//Called from the bullet when it hit something
[Command]
public void CmdHit(GameObject other,GameObject _bullet)
{
    Debug.Log(other.transform.name);
    GameObject bullet = _bullet;
    if (other.GetComponent<NetworkIdentity>() != null)
    {
        //Destroy the coin if you hit it
        if (other.transform.name.Equals("Coin"))
        {
            NetworkServer.Destroy(other.gameObject);
        }

        //Apply dmg to other player if hit it
        else if (other.transform.tag.Equals("Player"))
        {
            Player playerHit = GameManager.GetPlayer(other.transform.name);
            playerHit.TakeDamage(BulletForce);
        }
    }

    //Destroy the bullet if you hit anything
    NetworkServer.Destroy(bullet.gameObject);  
}

现在,如果我从 CmdShoot 中删除 [Command] 属性,远程玩家将无法射击,因为他没有网络服务器(据我所知)

我认为对于 CmdHit 来说也是一样,远程玩家将无法摧毁子弹或硬币,因为他没有网络服务器。

但是.. 即使没有 [Command] 属性,CmdHit 也能正常工作,我想知道为什么?

如果您查看 Unity 关于 remote actions 的文档,应该会对您有所帮助。当您将 [Command] 属性添加到方法时,您将该方法标记为一旦客户端调用它就会在服务器上执行的代码。

在您的情况下,这意味着一旦客户端输入导致拍摄(例如按 Space),您自己调用 CmdShoot(),然后将在服务器。这是一个需要发送到服务器的事件,否则远程玩家永远不会有那颗子弹。然而,CmdHit 是不必在服务器上执行的本地操作 - 正如您在自己的代码注释中所写,CmdHit 将在子弹击中某物时立即调用。鉴于子弹在两个客户端上都存在,它将击中两个客户端上的某些东西,因此不必通过网络发送信息。