Unable to reactivate an object that's been deactivated. C#
I'm trying to create a script where the player is able to cycle between their two weapons by pressing a button. At the moment I have it set to P, but that's just a random key I decided on.
using UnityEngine;
using System.Collections;
public class WeaponSwitching : MonoBehaviour
{
public enum gunCycle { Pistol, MachineGun }
public gunCycle GunCycle = gunCycle.Pistol;
private bool pistol, machineGun;
// Use this for initialization
void Start()
{
pistol = true;
machineGun = false;
}
void WeaponCycle()
{
if (Input.GetKeyDown(KeyCode.P))
{
if (pistol == true && machineGun == false)
{
machineGun = true;
pistol = false;
}
else if (pistol == false && machineGun == true)
{
pistol = true;
machineGun = false;
}
}
if (pistol == false)
{
if (GunCycle == gunCycle.Pistol)
{
gameObject.SetActive(false);
}
else if (pistol == true)
{
if (GunCycle == gunCycle.Pistol)
{
gameObject.SetActive(true);
}
}
}
if (machineGun == false)
{
if (GunCycle == gunCycle.MachineGun)
{
gameObject.SetActive(false);
}
else if (machineGun == true)
{
if (GunCycle == gunCycle.MachineGun)
{
gameObject.SetActive(true);
}
}
}
}
// Update is called once per frame
void Update()
{
WeaponCycle();
}
}
I've noticed, in the inspector, the machine gun will start off deactivated, which I want, but when I press P, not only does pistol deactivate, also wanted, but the machine gun doesn't reactivate, which is what I don't want. Any advice on what I've done wrong?
Answer by ScaniX · Aug 12, 2016 at 07:24 PM
EDIT: Recycle your scripts on the weapons to some nice ascii art and add this one instead to your singleton game object:
public class WeaponSwitching : MonoBehaviour
{
public GameObject[] weapons; // Assign the weapons here in the inspector
public int initialWeaponIndex; // Set the initial weapon index in the inspector
private selectedWeaponIndex;
// Use this for initialization
void Start()
{
// Your advertisement here!
selectedWeaponIndex = initialWeaponIndex;
ApplyWeaponStatus();
}
private void WeaponCycle()
{
if (Input.GetKeyDown(KeyCode.P))
{
selectedWeaponIndex = (selectedWeaponIndex + 1) % weapons.Length;
ApplyWeaponState();
}
}
// Update is called once per frame
void Update()
{
WeaponCycle();
}
private void ApplyWeaponStatus() {
for (int i=0; i<weapons.Length; i++)
weapons[i].SetActive(i == selectedWeaponIndex);
}
}
Works perfectly. Thanks! Quick question. How did you get the 'Size' in the inspector? Is it something that's built in, or the .Length maybe?
An array is automatically represented in the inspector in two parts: the length of the array and the members of the array. It is just the editor for that type. :)
Answer by Dave-Carlile · Aug 12, 2016 at 06:00 PM
When you deactivate a gameObject any components on it no longer run. Since your deactivation script lives on the object you're deactivating it will no longer run so won't see that you hit the toggle key again. The solution is to move the toggle functionality into a different script that lives on a game object that doesn't ever get deactivated.
Answer by josehzz112 · Aug 12, 2016 at 08:25 PM
I think you have complicated a simple problem. If you only want to switch weapons my approach would be:
using UnityEngine;
using System.Collections;
public class WeaponSwitching : MonoBehaviour
{
public enum gunCycle { Pistol, MachineGun }
public gunCycle GunCycle = gunCycle.Pistol;
private bool pistol, machineGun;
// Use this for initialization
void Start()
{
pistol = true;
machineGun = false;
}
void WeaponCycle()
{
if (Input.GetKeyDown(KeyCode.P))
{
if (pistol == true && machineGun == false)
{
machineGun = true;
pistol = false;
}
else if (pistol == false && machineGun == true)
{
pistol = true;
machineGun = false;
}
}
//Hide Pistol
if (pistol == false && GunCycle == gunCycle.Pistol)
{
gameObject.SetActive(false);
}
//Show Pistol
else if (pistol == true && GunCycle == gunCycle.Pistol)
{
gameObject.SetActive(true);
}
//Hide Machine Gun
if (machineGun == false && GunCycle == gunCycle.MachineGun)
{
gameObject.SetActive(false);
}
//Show Machine Gun
else if (machineGun == true && GunCycle == gunCycle.MachineGun)
{
gameObject.SetActive(true);
}
}
// Update is called once per frame
void Update()
{
WeaponCycle();
}
}
I don't know why you have that enum, I'm assuming its because both weapons have the same script right?.
Hope it helps.
Answer by HoneybunHero · Aug 13, 2016 at 03:00 PM
Thanks for the help so far, everyone. I haven't been able to get it to work yet, but I have made some progress so far. I now have a new issue, and a weird one at that. When the game first starts up, the pistol is set to true, and machine gun is set to false. When I press P, both weapons are set to true and false at the same time. I didn't even know this was possible. I figured an error would come up to stop that, or something. I've set a third variable in the enum called AlwaysActive. I've also created an empty game object and attached the script to this object. So now I'm able to freely switch between the states of the weapons, but now, which ever weapon I had active at the start of the game, stays active regardless of it being true, false, or both at the same time.
using UnityEngine;
using System.Collections;
public class WeaponSwitching : MonoBehaviour
{
public enum gunCycle { Pistol, MachineGun, AlwaysActive }
public gunCycle GunCycle = gunCycle.AlwaysActive;
private bool pistol, machineGun,AlwaysActive;
// Use this for initialization
void Start()
{
AlwaysActive = true;
pistol = false;
machineGun = true;
}
void WeaponCycle()
{
if (AlwaysActive == true && GunCycle == gunCycle.AlwaysActive)
{
if (Input.GetKeyDown(KeyCode.P))
{
if (pistol == true && machineGun == false)
{
machineGun = true;
pistol = false;
}
else if (pistol == false && machineGun == true)
{
pistol = true;
machineGun = false;
}
}
}
if (!pistol && GunCycle == gunCycle.Pistol)
{
gameObject.SetActive(false);
}
else if (pistol & GunCycle == gunCycle.Pistol)
{
gameObject.SetActive(true);
}
if (!machineGun && GunCycle == gunCycle.MachineGun)
{
gameObject.SetActive(false);
}
else if (machineGun && GunCycle == gunCycle.MachineGun)
{
gameObject.SetActive(true);
}
}
// Update is called once per frame
void Update()
{
WeaponCycle();
}
}
As you already included the info from my answer I edited it to include a simple script for switching. :)
I don't really understand your new setup, but the script cannot really work. If there is only a single script on the new game object and no script on the weapons (which was the goal), this script cannot work as it does not have a reference to the gameObjects to activate/deactivate.
A script with gunCycle.Always is never activating/deactivating anything anyway as the two ifs with those bodies are never entered.
No bool can be true and false. What do you mean? :)
It was returning both true and false. I set a Debug.Log in order to find out what state Pistol and $$anonymous$$achineGun were in before and after pressing P. Pistol would be true, $$anonymous$$achineGun would be false, and being counted each frame. Once I pressed P, the two of them would remain the same, but then right under, false for Pistol would come up, and true for $$anonymous$$achineGun, and all four would be counted each frame. I ended up changing the script entirely. $$anonymous$$y new version works, but I don't think it will work well enough for anything more than two weapons.
using UnityEngine; using System.Collections; public class WeaponSwitching : $$anonymous$$onoBehaviour { public GameObject weapon_02; // Use this for initialization %|321048895_3|% if (weapon_01.activeInHierarchy == true) weapon_01.SetActive(false); weapon_02.SetActive(true); %|877705829_7|% weapon_01.SetActive(true); %|837199719_9|% } } %|-1152763270_12|% void Update() { %|1596967021_15|% %|480419684_16|% } }
Well, I edited my answer yesterday to allow a list of weapons.
Your answer
Follow this Question
Related Questions
Why won't these objects deactivate? 1 Answer
I am trying to close the GUI if its already active and the user clicks 0 Answers
add button to switch cars 1 Answer
How do you activate a game object ? 1 Answer
Can't use SetActive (true) on collision 0 Answers