为什么 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
将在子弹击中某物时立即调用。鉴于子弹在两个客户端上都存在,它将击中两个客户端上的某些东西,因此不必通过网络发送信息。
我有这个来自我正在制作的多人射击游戏的脚本,我对 [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
将在子弹击中某物时立即调用。鉴于子弹在两个客户端上都存在,它将击中两个客户端上的某些东西,因此不必通过网络发送信息。