I have this script from a multiplayer shooter that I'm making , and I have a question about the use of the [Command] attribute
This is the code:
[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);
}
Now if I remove the [Command] attribute from CmdShoot , the remote player isn't able to shoot , because he has no NetworkServer (as far as I understand)
I would assume it would be the same thing for CmdHit , and the remote player wont be able to destroy the bullet or the coin , because he does not have a NetworkServer.
But.. CmdHit works fine even without the [Command] attribute, and Im wondering why?
If you check out Unity's documentation about remote actions that should help you out here. When you add the [Command]
attribute to a method you mark that method as code to be executed on the server once the client calls it.
In your case this means that as soon as there is input on the client which results in a shoot (pressing Space for example) you call CmdShoot()
yourself, which then will be executed on the server. This is an event that needs to be sent to the server, otherwise the remote player won't ever have that bullet. CmdHit
however is a local action that doesn't have to be executed on the server - as you wrote in your own code comment, CmdHit
will be called from the bullet as soon as it hits something. Given that the bullet exists on both clients, it will hit something on both clients, so that information doesn't have to be sent over on the network.