0
\$\begingroup\$

I am building a game where a weapon shoots prefab bullets. I am trying to make this a multiplayer game, so the bullets need to be spawned into the Network.

What happens right now is that if I shoot a bullet from a host, the bullet is shot, but doesn't appear on the client screen. If I shoot the bullet from the client, the bullet doesn't appear on either screen. In fact, the function CmdShoot() isn't even called, as the Debug.Log("Hello") is not called. Here is the current code:

public class Gun : MonoBehaviour
{

    private GameObject bulletPrefab;

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) {
            owner.GetComponent<PlayerSetup>().CmdShoot(bulletPrefab, transform.position, owner.name, GetComponentInParent<Weapon>().angle);
        }
    }
}
public class PlayerSetup : NetworkBehaviour
{

    void Start ()
    {
        // Disable components if not local player
    }

    [Command]
    public void CmdShoot(GameObject bulletPrefab, Vector3 position, string playerName, float angle)
    {
        Debug.Log("Hello");
        GameObject bullet = Instantiate(bulletPrefab, position, Quaternion.identity);
        bullet.name = "bullet: " + playerName;
        bullet.GetComponent<Rigidbody>().AddForce(Quaternion.AngleAxis(angle, Vector3.forward) * Vector3.right * bulletPrefab.GetComponent<Bullet>().force);
        Destroy(bullet, 10f);
        NetworkServer.Spawn(bullet);
    }
}

Edit:

This piece of code doesn't work either, gives the same result. No error, but the function is also not called. The Input is detected though:

    void Update() {
        if (Input.GetMouseButtonDown(0)) {
            CmdShoot();
        }
    }

    [Command]
    void CmdShoot()
    {
        Debug.Log("Shoot");
        GameObject bullet = Instantiate(gunComponent.bulletPrefab, gun.position, Quaternion.identity);
        bullet.name = "bullet: " + transform.name;
        bullet.GetComponent<Rigidbody>().AddForce(Quaternion.AngleAxis(GetComponentInChildren<Weapon>().angle, Vector3.forward) * Vector3.right * gunComponent.bulletPrefab.GetComponent<Bullet>().force);
        Destroy(bullet, 10f);
        NetworkServer.Spawn(bullet);
    }

```
\$\endgroup\$
1
\$\begingroup\$

First things first. You should inherit from the proper base class. NetworkBehavior is the way to go.

Then there are conditions that your prefab should meet before getting passed to the method. According to documentation the GameObject should have a NetworkIdentity attached in order to be transmitted. The complete list of argument restrictions can be found here.

There is also one more catch. The CommandAttribute can be used for Players invoking the method on Server side from Client side only. I think the intended usage is input syncing rather than a RPC-like behaviour.

For Server to client transmission use the ClientRpcs.

Hope this pushes you in the right direction. Cheers!

\$\endgroup\$
0
\$\begingroup\$

You want to make sure it is the localplayer shooting, and if not then just remove and/or return out of Update()

void Update() {
if(!isLocalPlayer){Destroy(gameObject); return; }
    if (Input.GetMouseButtonDown(0)) {
        CmdShoot();
    }
}
\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.