Mirror Spawning prefab from Client with client authority enabled crash due to command parameters bec

Mirror Spawning prefab from Client with client authority enabled crash due to command parameters become null

My code in player prefab has a component script that contains the following for spawning a bullet.
It’s using ‘Mirror’. The ‘NetworkTransform’ has ClientAuthority enabled.

void Update()
    {
        if (!isLocalPlayer)
        {
            return; // dont run if not the local player
        }

        // .... some code....

        UpdateAction();

        // ..... more code ....
    }
 
    void UpdateAction()
    {
        if (targetOther != null)
        {
            Shoot();
            targetOther = null;
        }
    }

    void Shoot()
    {
        print("Bullet in Shoot : " + bullet + "\n is null ? " + (bullet == null));
        CmdShoot(bullet, transform.position + new Vector3(0, 2, 0), targetOther.gameObject);
    }

    [Command]
    public void CmdShoot(GameObject bulletPrefab, Vector3 spawnPos, GameObject targetOther)
    {
        print("Bullet Prefab : " + bulletPrefab +"\n is null ? " + (bulletPrefab == null));
        GameObject go = Instantiate(bulletPrefab);
        print(go);
        go.transform.position = spawnPos;
        HomingAttack ha;
        if (go.TryGetComponent<HomingAttack>(out ha))
        {
            ha._target = targetOther;
        }
        NetworkServer.Spawn(go);
    }

The GameObject bullet is a variable defined as public GameObject bullet; in the script. I have assigned this variable a proper prefab which has a NetworkIdentity and a NetworkTransform. Also, the prefab is added to registered spawnable prefabs.

The problem is the code crashes when this part of code is run ( it runs when I right click on another player ) since it reports that the bullet variable is null.
I have checked this with the print statements on line 26 and 33.
When run by the host-server player: line 26 prints that it has a valid value but line 33 prints that it is null.
How should I fix this?
Thank you.

Solved it.
Why the error occurred was that the prefab I am passing is not initialized in the server (instead I had it initialized in the client !!! which is wrong for my purpose).

Solution:
Instead of passing the GameObject prefab instance from the client to server, I must pass the index of the prefab from the registered spawnable prefabs.
Then in the server (command function) I locate the prefab instance by using NetworkManager.singleton.spawnPrefabs[index_of_bullet_prefab]

So for example the code is now like this:

void Shoot()
    {
        CmdShoot(0, transform.position + new Vector3(0, 2, 0), targetOther.gameObject);
    }
    [Command]
    public void CmdShoot(int prefabIdx, Vector3 spawnPos, GameObject targetOther)
    {

        GameObject go = Instantiate(NetworkManager.singleton.spawnPrefabs[prefabIdx]);
        print(go);
        go.transform.position = spawnPos;
        HomingAttack ha;
        if (go.TryGetComponent<HomingAttack>(out ha))
        {
            ha._target = targetOther;
        }
        NetworkServer.Spawn(go);
    }

This issue was not there for targetOther variable, I think this is because that gameObject exists in the server. Currently all my targetOther values are players (clients). Maybe that is why I can use that without a problem on contrast.

2 Likes