Networking Weapon Switching in a Multiplayer FPS

Hi guys,
I’m fairly new to Unity and am working on a multiplayer FPS - the Brackeys tutorial on this has been a huge help, but I’m having a problem

My weapon switching script doesn’t work on the network, I’ve fiddled with it a ton, changing all the different methods to [Command], [Client] or [ClientRpc] and I just seem to be making more issues and essentially have no idea what I’m doing, so I’ll show you guys my code right now - it allows both players to switch their own weapons and works fine locally, and the host can see the client’s weapon switching, but the client can’t even see the hosts weapon at all.

How it works:
Array of weapon prefabs
The Start function calls CmdSetupWeapons(), which Instantiates all 3 possible weapons as children of weaponHolder
Start function then calls CmdEquipWeapon(0), which calls RpcEquipWeapon
RpcEquipWeapon disables all weapons that are not the specified one
PlayerController calls the ChangeWeapon function when I hit the controls

using UnityEngine;
using UnityEngine.Networking;

public class WeaponManager : NetworkBehaviour
{

[SerializeField]
private string weaponLayerName = "Weapon";

[SerializeField]
private Transform weaponHolder;

private Weapon currentWeapon;

[SerializeField]
private Weapon[] weapons;

private GameObject[] instanceWeapons;

private WeaponGFX currentGFX;

private void Start()
{
instanceWeapons = new GameObject[weapons.Length];
CmdSetupWeapons();
//On Spawn, equip primary weapon
CmdEquipWeapon(0);
}

[Command]
public void CmdSetupWeapons()
{
RpcSetupWeapons();
}

[ClientRpc]
public void RpcSetupWeapons()
{
for (int i = 0; i < instanceWeapons.Length; i++)
{
instanceWeapons[i] = Instantiate(weapons[i].graphics, weaponHolder.position, weaponHolder.rotation);
instanceWeapons[i].transform.SetParent(weaponHolder);
}
}

public Weapon GetCurrentWeapon()
{
return currentWeapon;
}

public WeaponGFX GetCurrentGFX()
{
return currentGFX;
}

public void ChangeWeapon(int newWeapon)
{
CmdEquipWeapon(newWeapon);
}

[Command]
void CmdEquipWeapon(int index)
{
RpcEquipWeapon(index);
}

[ClientRpc]
void RpcEquipWeapon(int index)
{
currentWeapon = weapons[index];

//Enable newWeapon, disable all others
for (int i = 0; i < weapons.Length; i++)
{
if (i == index)
{
instanceWeapons[i].gameObject.SetActive(true);
}
else
{
instanceWeapons[i].gameObject.SetActive(false);
}
}

Debug.Log(currentWeapon.name + " has been activated. ");

currentGFX = instanceWeapons[index].GetComponent<WeaponGFX>();
if (currentGFX == null)
{
Debug.LogError("No WeaponGFX component on the weapon: " + instanceWeapons[index].name);
}
}
}

Any help is greatly appreciated! Thanks!

objNetId = GetComponent<NetworkIdentity>();        // get the object's network ID
        objNetId.AssignClientAuthority(connectionToClient);    // assign authority to the player who is making the changes
        RpcFunction(); //call your RPC function
        objNetId.RemoveClientAuthority(connectionToClient);

I am not sure if this will work, but in other scripts i have had to assign client authority over the objects being changed.

Wtihin your Cmd function you need to assign authority to the local client.
Then call the Rpc client side function
then remove client authority