Character Switching Doesn't Work With Weapon Script on Weapon

Hi,

A video of the issue.

I’m following a tutorial series at the moment but for some reason I can’t seem to figure out a fix that will still allow the player to switch to a different character even when they have a weapon equipped that has the weapon script attached.

I have no idea what is causing the issue to be honest. I’ve tried tinkering with it all day but nothing seems to be working.

Here are the associated scripts:

Weapon.cs:

using UnityEngine;
using System.Collections;

public class Weapon : MonoBehaviour {
    public WeaponType TypeOfWeapon;
    public Character Controller;

    public Transform RightHandPoint;
    public Transform LeftHandPoint;

    public float MeleeDamage;

    public float GunDamage;

    public float BaseSpread;

    public float BaseIncreaseRate;

    public float MaxSpread;

    public float FOV = 45f;

    public Texture2D CrossHairTexture;

    float CurSpread;

    bool IsFiring;

    public bool IsAiming;

    Vector3 SpawnPointStartRot;

    public GameObject Sparks;

    Transform SpawnPoint;

    // Use this for initialization
    void Start () {
        CurSpread = BaseSpread;
        if (TypeOfWeapon == WeaponType.Gun)
        {
            SpawnPoint = GameManager.Instance.CurrentCharacter.Instance.GunSpawnPoint;
            SpawnPointStartRot = SpawnPoint.transform.localEulerAngles;
        }
    }
 
    // Update is called once per frame
    void Update () {
        if(GameManager.Instance.CurrentCharacter.Name == Controller.Name)
        {
            if (TypeOfWeapon == WeaponType.Gun)
            {
                if (Input.GetButton("Fire1"))
                {
                    Fire();
                }
            }
            else if (TypeOfWeapon == WeaponType.Melee)
            {
                MeleeHandler();
            }
        }

        if(Input.GetKey(KeyCode.Mouse1) || Input.GetButton("Aim"))
        {
            IsAiming = true;
        }
        else
        {
            IsAiming = false;
        }
    }

    void FixedUpdate()
    {
        if (IsAiming)
        {
            if(SpawnPoint != null)
            {
                CurSpread = 0;
                SpawnPoint.transform.localRotation = Quaternion.Euler(new Vector3(347f, 10.5f, 0f));
                Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, FOV, 0.25f);
            }
        }
        else
        {
            if(SpawnPoint != null)
            {
                CurSpread = BaseSpread;
                SpawnPoint.transform.localRotation = Quaternion.Euler(SpawnPointStartRot);
                Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 60, 0.25f);
            }
        }
    }

    void MeleeHandler()
    {
        if(Input.GetMouseButtonDown(0))
        {
         
        }
    }

    void OnCollisionEnter(Collision col)
    {
        PlayerController pc = col.collider.GetComponent<PlayerController>();
     
        if(pc)
        {
            pc.TakeDamage(MeleeDamage);
        }
    }

    void Fire()
    {
        RaycastHit hit;
        if(Physics.Raycast(SpawnPoint.transform.position, Spray(), out hit, 800))
        {
            Debug.Log("hit");
            Instantiate(Sparks, hit.point, Quaternion.FromToRotation(Vector3.forward, hit.normal));
            PlayerController pc = hit.collider.transform.root.GetComponent<PlayerController>();

            if(pc)
            {
                pc.TakeDamage(GunDamage);
            }
        }
    }

    Vector3 Spray()
    {
        float X = (1 - 2 * Random.value) * CurSpread;
        float Y = (1 - 2 * Random.value) * CurSpread;
        float Z = 1;
        return SpawnPoint.TransformDirection(new Vector3(X, Y, Z));
    }

    void OnGUI()
    {
        if(GameManager.Instance.CurrentCharacter.Name == Controller.Name)
        {
            Vector3 ScreenPos = Camera.main.WorldToScreenPoint(transform.root.TransformPoint(new Vector3(0, 0, 50)));
            float temp = CurSpread * 1000;
            GUI.DrawTexture(new Rect(ScreenPos.x + 5f + temp, (float)Screen.height - ScreenPos.y - 1f, 5f, 2f), CrossHairTexture);
            GUI.DrawTexture(new Rect(ScreenPos.x - 10f - temp, (float)Screen.height - ScreenPos.y - 1f, 5f, 2f), CrossHairTexture);
            GUI.DrawTexture(new Rect(ScreenPos.x - 1f, (float)Screen.height - ScreenPos.y - 10f - temp, 2f, 5f), CrossHairTexture);
            GUI.DrawTexture(new Rect(ScreenPos.x - 1f, (float)Screen.height - ScreenPos.y + 5f + temp, 2f, 5f), CrossHairTexture);
        }
    }
}

public enum WeaponType
{
    Gun,
    Melee
}

SequenceManager.cs:

using UnityEngine;
using System.Collections;
using UnityStandardAssets.Utility;

public class SequenceManager : MonoBehaviour {
    public CharacterTransistion CharSwitch;

    public static SequenceManager Instance;

    void Awake()
    {
        Instance = this;
    }

    public IEnumerator DoCharSwitch(Character c)
    {
        CharSwitch.Orbiter.enabled = false;
        int i = 0;
        while(i < 3)
        {
            if(i == 0)
            {
                CharSwitch.Follower.height = CharSwitch.Height;
                while (Mathf.Round(CharSwitch.Follower.transform.position.y) != CharSwitch.Height)
                    yield return new WaitForEndOfFrame();
            }

            if(i == 1)
            {
                Vector3 pos = new Vector3(c.Instance.transform.position.x, CharSwitch.Height, c.Instance.transform.position.z);
                CharSwitch.Follower.transform.position = Vector3.Lerp(CharSwitch.Follower.transform.position, pos, CharSwitch.Speed * Time.deltaTime);

                if (CharSwitch.Follower.transform.position != pos)
                {
                    yield return new WaitForEndOfFrame();
                }
            }

            if(i == 2)
            {
                CharSwitch.Follower.target = c.Instance.Lookpoint;
                CharSwitch.Follower.height = 2;
                CharSwitch.Orbiter.target = c.Instance.Lookpoint;
                GameManager.Instance.CanShowSwitch = true;
                CharSwitch.Orbiter.enabled = true;
                if ((int)CharSwitch.Follower.transform.position.y != 2)
                    yield return new WaitForEndOfFrame();
            }

            i++;
        }
        StopCoroutine("DoCharSwitch");
        yield return null;
    }
}

[System.Serializable]
public class CharacterTransistion
{
    public float Height;
    public float Speed;
    public SmoothFollow Follower;
    public MouseOrbit Orbiter;
}

PlayerController.cs:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]

public class PlayerController : MonoBehaviour {
    public Animator Anim;
    public bool CanPlay;
    public Character LocalCharacter;

    public Transform Hand;
    public Transform GunSpawnPoint;

    private List<Item> _inventory = new List<Item>();

    public float v;
    public float h;

    public bool AIRunning;

    public float Health;

    public bool IsAlive;

    public AI AIScript;

    public float Speed;

    public Transform Lookpoint;

    public float Direction;

    public Transform Aimpoint;

    public float RunAmount;

    public float RunIncreaseAmount = 0.1f;

    public float RunAmountLerpSpeed = 0.05f;

    public List<Item> Inventory
    {
        get
        {
            return _inventory;
        }
        set
        {
            _inventory = value;
        }
    }

    private Item _InHand;

    public Item InHand
    {
        get
        {
            return _InHand;
        }

        set
        {
            _InHand = value;
            Destroy(InHandInstance);
            if(value != null)
            {
                Weapon w = value.InstancePrefab.GetComponent<Weapon>();
                if(w)
                {
                    w.Controller = LocalCharacter;

                    if(w.TypeOfWeapon == WeaponType.Gun)
                    {
                        InHandInstance = Instantiate(value.InstancePrefab.gameObject, GunSpawnPoint.position, GunSpawnPoint.rotation) as GameObject;
                        InHandInstance.transform.parent = GunSpawnPoint;
                    }
                    else
                    {
                        InHandInstance = Instantiate(value.InstancePrefab.gameObject, Hand.position, Hand.rotation) as GameObject;
                        InHandInstance.transform.parent = Hand;
                    }
                }
                else
                {
                    InHandInstance = Instantiate(value.InstancePrefab.gameObject, Hand.position, Hand.rotation) as GameObject;
                    InHandInstance.transform.parent = Hand;
                }
            }

            if(GameManager.Instance.Characters.IndexOf(LocalCharacter) == 0)
            {
                SaveManager.Instance.p1_Hand = InHand;
            }

            if (GameManager.Instance.Characters.IndexOf(LocalCharacter) == 1)
            {
                SaveManager.Instance.p2_Hand = InHand;
            }

            if (GameManager.Instance.Characters.IndexOf(LocalCharacter) == 2)
            {
                SaveManager.Instance.p3_Hand = InHand;
            }
        }

    }

    private GameObject InHandInstance;
 
    // Use this for initialization
    void Start ()
    {
        Health = 40f;

        IsAlive = true;

        StartCoroutine(Timer());

        SetRigidbodys(true);

        if(GameManager.Instance.Characters.IndexOf(LocalCharacter) == 0)
        {
            SaveManager.Instance.P1_Inventory = Inventory;
        }

        if(GameManager.Instance.Characters.IndexOf(LocalCharacter) == 1)
        {
            SaveManager.Instance.P2_Inventory = Inventory;
        }

        if (GameManager.Instance.Characters.IndexOf(LocalCharacter) == 2)
        {
            SaveManager.Instance.P3_Inventory = Inventory;
        }

        AIScript = GetComponent<AI>();
    }

    IEnumerator Timer()
    {
        yield return new WaitForSeconds(0.001f);
        CanPlay = true;
        yield return new WaitForSeconds(0.001f);
        CanPlay = false;
    }
 
    // Update is called once per frame
    void Update ()
    {
        if(CanPlay)
        {
            JoystickToEvents.Do(transform, Camera.main.transform, ref Speed, ref Direction);
            AIScript.Agent.enabled = false;
            Anim.applyRootMotion = true;
            //v = Input.GetAxis("Vertical");
            //h = Input.GetAxis("Horizontal");
            if(Input.GetButton("Run"))
            {
                RunAmount += RunIncreaseAmount;
            }
            else
            {
                RunAmount = Mathf.Lerp(RunAmount, 0, RunAmountLerpSpeed);
            }
         
            //Anim.SetFloat("Speed", Speed + 1);
            RunAmount = Mathf.Clamp01(RunAmount);
             
            Anim.SetFloat("Speed", Speed + RunAmount);

            Anim.SetFloat("Direction", Direction * 2);

            if (Input.GetKeyDown(KeyCode.U))
            {
                if (IsAlive)
                {
                    TakeDamage(1000);
                }
                else
                {
                    Revive();
                }
            }
        }
        else
        {
            Anim.SetFloat("Speed", 1);
        }

        if(InHandInstance != null)
        {
            Weapon w = InHandInstance.GetComponent<Weapon>();

            if (w.IsAiming)
            {
                GameManager.Instance.Follower.target = null;
                GameManager.Instance.Orbiter.target = Aimpoint;
                GameManager.Instance.Orbiter.distance = 0;
                GameManager.Instance.Orbiter.yMaxLimit = 30;
             
                GameManager.Instance.Orbiter.xSpeed = 100;
                GameManager.Instance.Orbiter.ySpeed = 60;
             
                //Camera.main.transform.position = Aimpoint.position;
            }
            else
            {
                GameManager.Instance.Follower.target = Lookpoint;
                GameManager.Instance.Orbiter.target = Lookpoint;
                GameManager.Instance.Orbiter.distance = 5;
                GameManager.Instance.Orbiter.yMaxLimit = 80;

                GameManager.Instance.Orbiter.xSpeed = 250;
                GameManager.Instance.Orbiter.ySpeed = 120;
            }
        }
        else
        {
            // nothing
        }
    }

    void OnAnimatorIK()
    {
        if(Anim != null)
        {
            if(InHandInstance != null)
            {
                Weapon w = InHandInstance.GetComponent<Weapon>();

                if(w != null && w.TypeOfWeapon == WeaponType.Gun)
                {
                    Anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
                    Anim.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);

                    Anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
                    Anim.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);

                    Anim.SetIKPosition(AvatarIKGoal.LeftHand, w.LeftHandPoint.position);
                    Anim.SetIKRotation(AvatarIKGoal.LeftHand, w.LeftHandPoint.rotation);

                    Anim.SetIKPosition(AvatarIKGoal.RightHand, w.RightHandPoint.position);
                    Anim.SetIKRotation(AvatarIKGoal.RightHand, w.RightHandPoint.rotation);

                    if(w.IsAiming)
                    {
                        Anim.SetLookAtWeight(1, 1, 2);
                        Anim.SetLookAtPosition(Camera.main.transform.root.TransformPoint(new Vector3(0, 0, 50)));
                    }
                }
            }
        }
    }

    public void TakeDamage(float damage)
    {
        if(IsAlive)
        {
            Debug.Log(damage);
            Health -= damage;
            if (Health <= 0)
            {
                Die();
                AIScript.Agent.speed = 0;
            }
        }
    }

    void Die()
    {
        IsAlive = false;
        Anim.enabled = false;
        GetComponent<Collider>().enabled = false;
        GetComponent<Rigidbody>().isKinematic = true;
        AIScript.Agent.enabled = false;
        SetRigidbodys(false);
    }

    public void Revive()
    {
        IsAlive = true;
        Anim.enabled = true;
        GetComponent<Collider>().enabled = true;
        GetComponent<Rigidbody>().isKinematic = false;
        AIScript.Agent.enabled = true;
        SetRigidbodys(true);
        transform.position = LocalCharacter.HomeSpawn.position;
        transform.rotation = LocalCharacter.HomeSpawn.rotation;
        Health = 40f;
    }

    void SetRigidbodys(bool active)
    {
        Rigidbody[] temp = GetComponentsInChildren<Rigidbody>();
        foreach (Rigidbody r in temp)
        {
            if (r.gameObject != gameObject)
            {
                r.GetComponent<Collider>().enabled = !active;
                r.isKinematic = active;
            }
        }
    }
}

GameManager.cs:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityStandardAssets.Utility;

public class GameManager : MonoBehaviour {

    public List<Character> Characters = new List<Character>();
    public List<Item> AllItems = new List<Item>();
    public Location[] PossibleLocations;
    public LootChest[] AllChests;
    public Character CurrentCharacter;
    bool ShowCharWheel;
    public int SelectedCharacter;
    int LastCharacter;
    public static GameManager Instance;
    public bool CanShowSwitch = true;

    public Camera MainCamera
    {
        get
        {
            return Camera.main;
        }
    }

    public SmoothFollow Follower;
    public MouseOrbit Orbiter;

    public LootChest SelectedChest;

    void Awake()
    {
        Instance = this;
        AllChests = FindObjectsOfType<LootChest>();
        PossibleLocations = FindObjectsOfType<Location>();
        foreach(Character c in Characters)
        {
            GameObject go = Instantiate(c.PlayerPrefab, c.HomeSpawn.position, c.HomeSpawn.rotation) as GameObject;
            c.Instance = go.GetComponent<PlayerController>();
            c.Instance.LocalCharacter = c;
        }
        ChangeCharacterStart(Characters[PlayerPrefs.GetInt("SelectedChar")]);
    }

    // Use this for initialization
    void Start () {
        Follower = MainCamera.GetComponent<SmoothFollow>();
        Orbiter = MainCamera.GetComponent<MouseOrbit>();

        StartCoroutine(Timer());
    }
 
    public LootChest FindChestWithID(int id)
    {
        foreach(LootChest lc in AllChests)
        {
            if(lc.ID == id)
            {
                return lc;
            }
        }
        return null;
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKey(KeyCode.C))
        {
            ShowCharWheel = true;
            Time.timeScale = 0.5f;
        }
        else
        {
            ShowCharWheel = false;
            Time.timeScale = 1;
        }

        if(Input.GetButton("Snap Back"))
        {
            Orbiter.enabled = false;
            Orbiter.x = CurrentCharacter.Instance.transform.eulerAngles.y;
            Orbiter.y = Camera.main.transform.eulerAngles.x;
        }
        else if (CurrentCharacter.IsInVehicle || !CanShowSwitch)
        {
            Orbiter.enabled = false;
        }
        else
        {
            Orbiter.enabled = true;
        }

        /*if(Input.GetButtonDown("Snap Back"))
        {
            Orbiter.enabled = false;
            Camera.main.transform.rotation = Quaternion.Slerp(Camera.main.transform.rotation, CurrentCharacter.Instance.transform.rotation, 100 * Time.deltaTime);
        }

        if(Orbiter.enabled == false)
        {
            if(Vector3.Distance(Camera.main.transform.eulerAngles, CurrentCharacter.Instance.transform.eulerAngles) < 1)
            {
                Orbiter.enabled = true;
            }
        } */
    }

    void ChangeCharacterStart(Character c)
    {
        LastCharacter = SelectedCharacter;
        SelectedCharacter = Characters.IndexOf(c);
        CurrentCharacter = c;
        Characters[LastCharacter].Instance.GetComponent<PlayerController>().CanPlay = false;
        Characters[SelectedCharacter].Instance.GetComponent<PlayerController>().CanPlay = true;
        Follower.target =  Characters[SelectedCharacter].Instance.Lookpoint.transform;
        Camera.main.GetComponent<MouseOrbit>().target = Characters[SelectedCharacter].Instance.Lookpoint;
        PlayerPrefs.SetInt("SelectedChar", SelectedCharacter);
    }

    void ChangeCharacter(Character c)
    {
        c.Instance.GetComponent<AI>().DoneHome = false;

        if (Vector3.Distance(Characters[SelectedCharacter].Instance.transform.position, c.Instance.transform.position) > 10)
        {
            SequenceManager.Instance.StartCoroutine("DoCharSwitch", c);
            CanShowSwitch = false;
            LastCharacter = SelectedCharacter;
            CurrentCharacter = c;
            SelectedCharacter = Characters.IndexOf(c);
            Characters[LastCharacter].Instance.GetComponent<PlayerController>().CanPlay = false;
            Characters[SelectedCharacter].Instance.GetComponent<PlayerController>().CanPlay = true;
            PlayerPrefs.SetInt("SelectedChar", SelectedCharacter);
        }
        else
        {
            LastCharacter = SelectedCharacter;
            SelectedCharacter = Characters.IndexOf(c);
            CurrentCharacter = c;
            Characters[LastCharacter].Instance.GetComponent<PlayerController>().CanPlay = false;
            Characters[SelectedCharacter].Instance.GetComponent<PlayerController>().CanPlay = true;
            PlayerPrefs.SetInt("SelectedChar", SelectedCharacter);
            Camera.main.GetComponent<SmoothFollow>().target = Characters[SelectedCharacter].Instance.Lookpoint;
            Camera.main.GetComponent<MouseOrbit>().target = Characters[SelectedCharacter].Instance.Lookpoint;
        }

        if(!c.Instance.IsAlive)
        {
            c.Instance.Revive();
        }
    }

    IEnumerator Timer()
    {
        yield return new WaitForSeconds(0.05f);
        Characters[SelectedCharacter].Instance.GetComponent<PlayerController>().CanPlay = true;
    }

    void OnGUI()
    {
        if (ShowCharWheel && CanShowSwitch)
        {
            GUILayout.BeginArea(new Rect(Screen.width - 64, Screen.height - 192, 64, 192));
            foreach(Character c in Characters)
            {
                if (GUILayout.Button(c.Icon, GUILayout.Width(64), GUILayout.Height(64)))
                {
                    ChangeCharacter(c);
                }
            }
            GUILayout.EndArea();
        }
    }

    public Item FindItem(string itemName)
    {
        foreach(Item i in AllItems)
        {
            if(i.Name == itemName)
            {
                return i;
            }
        }
        return null;
    }

    public Location FindLocationOfType(LocationType i)
    {
        foreach (Location l in PossibleLocations)
        {
            if (l.Type == i)
            {
                return l;
            }
        }
        return null;
    }
}

[System.Serializable]
public class Character
{
    public string Name;
    public Texture2D Icon;
    public GameObject PlayerPrefab;
    public PlayerController Instance;
    public Transform HomeSpawn;
    public bool IsInVehicle;
}

[System.Serializable]
public class Item
{
    public string Name;
    public Texture2D Icon;
    public bool Selectable;
    public ItemInstance InstancePrefab;

    public static Item None
    {
        get
        {
            return new Item();
        }
    }
}

A lot of code I know, but that’s the scripts that all interconnect to work together to do stuff. I have other weapons in the game that will allow the player to switch characters fine; the problem is when you equip a weapon that has a weapon script – the character switching messes up only on that.

Thanks.

A video of the issue.