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.