```cs
// Error is explained on line 154
using System;
using System.Collections.Generic;
using JebScripts.Game.Combat;
using JebScripts.Game.Input;
using Unity.Netcode;
using UnityEngine;
namespace JebScripts.Game.Player
{
public class PlayerCombatController : NetworkBehaviour
{
[Header("Input")]
[SerializeField] InputReader inputReader;
[Header("Gun")]
[SerializeField] private GunController[] startingGuns;
[SerializeField] private Transform gunTransform;
// Weapon Inventory
private GunController activeGunController;
[SerializeField] private int maxWeapons = 2;
private NetworkVariable<int> activeWeaponsSlot = new NetworkVariable<int>();
private List<GunController> ownedGuns = new();
public Action<GunController> onWeaponSlotChanged;
// Load Functions
public override void OnNetworkSpawn()
{
SetupGunControls();
if (!IsOwner)
return;
inputReader.OnFireEvent += OnFire;
inputReader.OnFireCanceledEvent += OnFireCanceled;
inputReader.OnReloadEvent += OnReload;
inputReader.OnAimEvent += OnAim;
inputReader.OnDirectChangeWeaponSlot += RequestActiveWeaponSlotChange;
}
public override void OnNetworkDespawn()
{
activeWeaponsSlot.OnValueChanged -= WeaponSlotChanged;
if (!IsOwner)
return;
inputReader.OnFireEvent -= OnFire;
inputReader.OnFireCanceledEvent -= OnFireCanceled;
inputReader.OnReloadEvent -= OnReload;
inputReader.OnAimEvent -= OnAim;
inputReader.OnDirectChangeWeaponSlot -= RequestActiveWeaponSlotChange;
}
private void SetupGunControls()
{
activeWeaponsSlot.OnValueChanged += WeaponSlotChanged;
if (IsServer)
{
foreach (GunController weapon in startingGuns)
{
AddGunToInventory(weapon, false);
}
RequestActiveWeaponSlotChange(0);
}
if(IsClient)
WeaponSlotChanged(-1, activeWeaponsSlot.Value);
}
// Firing
private void OnFire()
{
activeGunController.StartShooting();
}
private void OnFireCanceled()
{
activeGunController.StopShooting();
}
// Aiming
private void OnAim(Vector2 value)
{
if (Camera.main == null)
return;
Vector2 worldTarget = Camera.main.ScreenToWorldPoint(value);
Vector2 aimDirection = worldTarget - (Vector2)gunTransform.position;
float angle = Mathf.Atan2(aimDirection.y, aimDirection.x) * Mathf.Rad2Deg;
gunTransform.rotation = Quaternion.Euler(0, 0, angle);
gunTransform.localScale = aimDirection.x < 0 ? new Vector3(1, -1, 1) :
new Vector3(1, 1, 1);
}
// Reloading
private void OnReload()
{
activeGunController.Reload();
}
// Weapon Changing
private void RequestActiveWeaponSlotChange(int newSlot)
{
if (IsServer)
{
activeWeaponsSlot.Value = Mathf.Clamp(newSlot, 0, ownedGuns.Count - 1);;
}
else
{
RequestActiveWeaponSlotChangeServerRPC(newSlot);
}
}
[ServerRpc]
private void RequestActiveWeaponSlotChangeServerRPC(int slot)
{
ApplyActiveWeaponSlotChange(slot);
}
private void ApplyActiveWeaponSlotChange(int slot)
{
if (ownedGuns == null || ownedGuns.Count == 0 || slot == activeWeaponsSlot.Value)
return;
activeWeaponsSlot.Value = Mathf.Clamp(slot, 0, ownedGuns.Count - 1);
}
private void WeaponSlotChanged(int previousvalue, int newvalue)
{
if (previousvalue >= 0 && previousvalue < ownedGuns.Count)
{
GunController previousGun = ownedGuns[previousvalue];
if (previousGun)
previousGun.ShowVisuals(false);
}
if (newvalue < 0 || newvalue >= ownedGuns.Count)
return;
GunController nextGun = ownedGuns[newvalue];
if (!nextGun)
return;
nextGun.ShowVisuals(true);
activeGunController = nextGun;
}
// Adding Guns
// This Is Where I am having issues with the my code, im trying to spawn in a gun prefab which has a network behaviour on it (Gun Controller) but all that happens is it spawns the gun into the scene. No parenting so doesnt attatch to the intedned socket(trasnform) so doesnt follow the player. On the server the player can still fire and switch the gun that is active like in the functions above but on any late joining they cant fire their weapons, However they can change their active gun but it only shows on the server client.
// Spawn Guns in and store them in each players inventory
// allow each player to control their gun
// Should attatch to socket on each players prefab at runtime
// switching between active guns should show on everyones version
private void AddGunToInventory(GunController newGun, bool equip = true)
{
if (!IsServer) return;
int targetIndex = ownedGuns.Count < maxWeapons ? ownedGuns.Count : activeWeaponsSlot.Value;
if (targetIndex < ownedGuns.Count && ownedGuns[targetIndex] != null)
{
ownedGuns[targetIndex].NetworkObject.Despawn();
Destroy(ownedGuns[targetIndex].gameObject);
ownedGuns[targetIndex] = null;
}
GunController gun = Instantiate(newGun, transform);
NetworkObject networkObj = gun.GetComponent<NetworkObject>();
networkObj.Spawn();
if (targetIndex < ownedGuns.Count)
ownedGuns[targetIndex] = gun;
else
ownedGuns.Add(gun);
//newGunVisual.transform.localPosition = Vector3.zero;
//newGunVisual.transform.localRotation = Quaternion.identity;
gun.ShowVisuals(equip);
if (equip)
RequestActiveWeaponSlotChange(targetIndex);
}
}
}
```