Need help with synchronizing weapon pickup and switching.

Hope you’re all good! I’m working on a multiplayer game using netcode for game objects and I’m stuck on syncing weapon pickup and switching between players. I’ve got it working for single-player, but now I’m struggling to synchronize this across multiple clients.

I need some guidance on how to sync weapon pickup and switching in a multiplayer game. If you’ve got any tips, best practices, or other ways to do it, I’d really appreciate your help.

I’ve been trying to implement a solution based on what I found in the forums, but I’m struggling.

Here’s what I’ve discovered so far:

  • Players ask the server if they can pick up a weapon.
  • If yes, the server instantiates the weapon on all clients (non-network object).
  • The weapon on the ground is hidden.

However, I’m having trouble implementing this. Also, I’ve got a character armature in my game, so attaching the weapon is a bit tricky as I can’t make it a network object.

This is my script for weapon pickup and switching

using System.Collections;
using UnityEngine;

public class WeaponPickupAndDrop : MonoBehaviour
{
    public enum WeaponSlot
    {
        Primary = 0,
        Secondary = 1
    }
    public Camera mainCamera;
    public float pickUpRange;
    public LayerMask pickUpLayer;
    public Transform[] weaponSlots;
    public Animator rigController;
    public CharacterAiming characterAiming;
    GameObject [] equippedWeapon = new GameObject[2];    
    int activeWeaponIndex;

    public void Start()
    {
        mainCamera = Camera.main;

        rigController.updateMode = AnimatorUpdateMode.AnimatePhysics;
        rigController.cullingMode = AnimatorCullingMode.AlwaysAnimate;
        rigController.updateMode = AnimatorUpdateMode.Normal;
    }

    GameObject GetWeapon(int index)
    {
        if(index < 0 || index >= equippedWeapon.Length)
        {
            return null;
        }
        return equippedWeapon[index];
    }

    public GameObject GetActiveWeapon()
    {
        return GetWeapon(activeWeaponIndex);
    }

    public void PickUp(GameObject newWeapon)
    {
        int weaponSlotIndex = (int) newWeapon.GetComponent<GunSystem>().weaponSlot;
        var weapon = GetWeapon(weaponSlotIndex);
        if(weapon)
        {
            Destroy(weapon);
        }
        weapon = newWeapon;
        weapon.GetComponent<Recoil>().characterAiming = characterAiming;
        weapon.GetComponent<Recoil>().rigController = rigController;
        weapon.transform.SetParent(weaponSlots[weaponSlotIndex]);
        weapon.transform.localPosition = Vector3.zero;
        weapon.transform.localRotation = Quaternion.identity;

        //rigController.Play("equip_"+ weapon.GetComponent<GunSystem>().weaponName);
        equippedWeapon[weaponSlotIndex] = weapon;

        //activeWeaponIndex = weaponSlotIndex;
        SetActiveWeapon(weaponSlotIndex);
    }

    void ToggleActiveWeapon()
    {
        bool isHolstered = rigController.GetBool("holsterWeapon");
        if(isHolstered)
        {
            StartCoroutine(ActivateWeapon(activeWeaponIndex));
        }
        else
        {
            StartCoroutine(HolsterWeapon(activeWeaponIndex));
        }
    }

    void SetActiveWeapon(int weaponSlotIndex)
    {
        int holsterIndex = activeWeaponIndex;
        int activateIndex = weaponSlotIndex;

        if(holsterIndex == activateIndex)
        {
            holsterIndex = -1;
        }
        StartCoroutine(SwitchWeapon(holsterIndex, activateIndex));
    }

    IEnumerator SwitchWeapon(int holseterIndex, int activateIndex)
    {
        yield return StartCoroutine(nameof(HolsterWeapon), holseterIndex);
        yield return StartCoroutine(nameof(ActivateWeapon), activateIndex);
        activeWeaponIndex = activateIndex;
    }
    IEnumerator HolsterWeapon(int index)
    {
        var weapon = GetWeapon(index);
        if(weapon)
        {
            weapon.GetComponent<GunSystem>().enabled = false;
            rigController.SetBool("holsterWeapon", true);
            do
            {
                yield return new WaitForEndOfFrame();
            }
            while(rigController.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f);
        }
    }
    IEnumerator ActivateWeapon(int index)
    {
        var weapon = GetWeapon(index);
        if(weapon)
        {
            rigController.SetBool("holsterWeapon", false);
            rigController.Play("equip_"+ weapon.GetComponent<GunSystem>().weaponName);
            do
            {
                yield return new WaitForEndOfFrame();
            }
            while(rigController.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f);
            weapon.GetComponent<GunSystem>().enabled = true;
        }
    }

    void SwitchWeaponByMouse(float scrollValue)
    {
        if(equippedWeapon[0] != null && equippedWeapon[1] != null)
        {
            if (scrollValue > 0f)
            {
              
                SetActiveWeapon((int)WeaponSlot.Secondary);
            }
            else if (scrollValue < 0f)
            {
                SetActiveWeapon((int)WeaponSlot.Primary);
            }
        }
    }



    void Update()
    {
        if(Input.GetKeyDown(KeyCode.F))
        {
            if(Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out RaycastHit hit, pickUpRange, pickUpLayer))
            {
                var newWeapon = Instantiate(hit.transform.gameObject);
                PickUp(newWeapon);
            }
        }
      
        if(Input.GetKeyDown(KeyCode.X))
        {
            ToggleActiveWeapon();
        }

        if(Input.GetKeyDown(KeyCode.Alpha1))
        {
            SetActiveWeapon((int)WeaponSlot.Primary);
        }
        if(Input.GetKeyDown(KeyCode.Alpha2))
        {
            SetActiveWeapon((int)WeaponSlot.Secondary);
        }

        if (Input.GetAxis("Mouse ScrollWheel") != 0f)
        {
            SwitchWeaponByMouse(Input.GetAxis("Mouse ScrollWheel"));
        }



    }
}

Please help !!!

did you find a solution to this?