Error with shooting at clients

I did shooting in the game and everything works fine for the host, but when clients try to shoot, an error appears “Spawned object not found when handling Command message netId=0”. I made (requiresAuthority = false) in the code where [Command] is used, but it didn’t help. I set up logging and all players are told that the weapon has netId 0.

This is the part of the inventory code that is responsible for the appearance of weapons in hands.

private void NewItemSelected()
    {
        if (currentItemInHand != null)
        {
            if (isServer)
            {
                NetworkServer.Destroy(currentItemInHand);
            }
            Destroy(currentItemInHand);
            currentItemInHand = null;
        }

        if (inventoryList.Count == 0) return;

        ItemSyncData selectedItemSO = inventoryList[selectedItem];

        ItemSO itemData = Resources.Load<ItemSO>($"Items/{selectedItemSO.itemType}");
        if (itemData == null)
        {
            Debug.LogError($"Failed to load ItemSO: {selectedItemSO.itemType}");
            return;
        }

        GameObject prefab = Resources.Load<GameObject>($"Prefabs/{itemData.itemPrefab}");
        if (prefab == null)
        {
            Debug.LogError($"Failed to load item prefab: {itemData.itemPrefab}");
            return;
        }

        currentItemInHand = Instantiate(prefab, handTransform.position, handTransform.rotation);
        var netId = currentItemInHand.GetComponent<NetworkIdentity>().netId;
        Debug.Log($"Client can shoot, object netId: {netId}");

        SetItemScale(currentItemInHand);
        DisablePhysicsOnItem(currentItemInHand);
        AttachItemToHand(currentItemInHand);

        if (isServer)
        {
            if (NetworkServer.active)
            {
                NetworkServer.Spawn(currentItemInHand);
                Debug.Log("Spawned");
            }

            NetworkIdentity itemNetworkIdentity = currentItemInHand.GetComponent<NetworkIdentity>();
            if (itemNetworkIdentity != null)
            {
                itemNetworkIdentity.AssignClientAuthority(connectionToClient);
            }

            RpcShowItemInHand(currentItemInHand);
            TargetUpdateHand(connectionToClient, currentItemInHand);
        }

        currentAnim = itemData.NumAnim;
        gameObject.GetComponent<FPScontroller>().HoldItems = true;
        ArmsAnim.SetInteger("arms", currentAnim);

    }

This method is on the weapon, it is triggered when the button is pressed. According to the logs, the pressing occurs on the client, but there is no shooting.

[Command(requiresAuthority = false)]
    private void CmdRequestShoot()
    {
        if (bulletsLeft <= 0 || isReloading) return;
        Debug.Log("Shooting");

        bulletsLeft--;
        RpcHandleShoot();

        Vector3 shootDirection = fpsCam.transform.forward;
        RaycastHit hit;
        if (Physics.Raycast(fpsCam.transform.position, shootDirection, out hit, range, targetLayer))
        {
            if (hit.collider != null)
            {
                Debug.Log("Hit: " + hit.collider.name);

                Entity target = hit.collider.GetComponent<Entity>();
                Entity head = hit.collider.GetComponentInParent<Entity>();

                if (target != null)
                {
                    CmdDealDamage(target.netIdentity, damage);
                }

                if (head.tag == "Head")
                {
                    CmdHeadshot(head.netIdentity, damage * 5);
                }
            }
        }
    }

You are instantiating the weapon indiscriminately for everyone. Then you instruct the server to also spawn the object. This will create instances of the object for everyone, but this time it‘s an actual network synchronized object. The other ones aren‘t and shouldn‘t exist.

But you got half of it right. Next, remove all networking from the weapon. Instantiate it for everyone as usual. Route all network traffic through a central player script. Both attacking and weapon switching, which should be a simple NetworkVariable recording the index of the currently active weapon.

This avoids all the network parenting issues you are going to face otherwise. There is no point, and no need to make the weapon itself a network object. Same goes for any other object that is part of the player hierarchy, or any other network object’s hierarchy. It‘s easier and less error prone to let the network object‘s root handle all networking, and have every other component communicate through that script.