GameObject SetActive not reactivating
Hey, I am running into an issue with using SetActive() to deactivate and then reactivate a game object. I am running Unity version 4.0.1f2. I've taken a basic cube and added the following script to it:
using UnityEngine;
using System.Collections;
public class VisibilityChangeScript : MonoBehaviour
{
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
print (this.gameObject.activeSelf);
if (Input.GetKey(KeyCode.Q))
{
this.gameObject.SetActive(false);
}
else if (Input.GetKey(KeyCode.E))
{
this.gameObject.SetActive(true);
}
}
}
When I hit the Q key, the cube becomes inactive and it stops printing the cube's activity to the console. However, when I hit the E key, the cube never becomes active again.
Am I missing something really simple here? Is it possibly that the object is getting removed completely from the system, so it can't actually be reactivated?
Thanks!
Answer by SaviorXTanren · Jan 31, 2013 at 08:06 AM
n/m, I was able to figure this one out pretty quickly. Wasn't thinking to straight.
For those that run into this issue, this will never work because one the game object becomes inactive, it's Update() method will not be called. So, the SetActive(true) can never be reached and the object will remain inactive.
To fix this, you need to have a parent game object that contains all the child game objects you want to make inactive and reactive. Then, add the following script to the parent:
using UnityEngine;
using System.Collections;
public class VisibilityChangeScript : MonoBehaviour
{
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
foreach (Transform child in this.transform)
{
if (Input.GetKey(KeyCode.Q))
{
child.gameObject.SetActive(false);
}
else if (Input.GetKey(KeyCode.E))
{
child.gameObject.SetActive(true);
}
}
}
}
hey there. So I'm running into the same issue, kinda. I have a gameobject with a particle generator, I am attempting to have the particle generator active only when you enter the collider, changing later to keypress. but for now i'm testing the active/inactive aspects. I got this to work for a light that is a child of the parent but not the gameobject. can you help?
shrine$$anonymous$$ain is the gameObject with the particle emitter. that i'm trying to activate and inactivate. starting with it inactive, and activating onCollisionEnter.
private var LightActive : Light;
private var shrine$$anonymous$$ain : GameObject;
private var isActive:boolean;
function Awake(){
LightActive = GetComponentInChildren(Light);
LightActive.enabled = false;
child.gameobject.shrine$$anonymous$$ain.SetActive = false;
}
function Start(){
if(isActive){
LightActive.enabled = false;
}
isActive = false;
}
function Update(){
if(isActive){
LightActive.enabled = true;
}
else{
LightActive.enabled = false;
}
}
function OnTriggerEnter(){
isActive = true;
}
Answer by Berenger · Jan 31, 2013 at 08:06 AM
Update is running only if the component is enabled AND the game object is active. Use a coroutine instead.
Odd, that's what I'm doing. I have a coroutine set, but I still can't get it to reactivate.
Answer by Jerz · Nov 16, 2016 at 07:27 AM
Looks like the reason is that "find" only works for active game objects.
The real fix is to create a game object variable, then assign it via "find, then do whatever you want using the variable afterward.
info found here: http://answers.unity3d.com/questions/568107/setactivetrue-not-working.html
Here are two buttons I have. The "transaction_button" will set the "transaction_canvas" to setactive(false). The "outlook_button" will set the "transaction_canvas" to setactive(true).
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class transaction_button : MonoBehaviour {
void Start()
{
Button btn = this.GetComponent<Button>();
btn.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
Camera.main.backgroundColor = new Color32(64, 161, 81, 255);
//GameObject.Find("Title_Text").GetComponent<Text>().text = "Expense Transaction";
GameObject.Find("Transaction_Canvas").SetActive(false);
}
}
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class outlook_button : MonoBehaviour {
GameObject testObject;
void Start()
{
testObject = GameObject.Find("Transaction_Canvas");
Button btn = this.GetComponent<Button>();
btn.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
Camera.main.backgroundColor = new Color32(61, 136, 188, 255);
testObject.SetActive(true);
}
}
you'll notice that the "transaction_button" doesn't have the game object variable, so it will only work if the object i'm "finding" is active. This is a bad idea and will give the following error if clicked twice in a row (without clicking the "outlook_button"). NullReferenceException: Object reference not set to an instance of an object
this is a pain to do. making an empty game object that is the parent for everything else is a lot easier, even if it is a funky work around.
Answer by drakedane · Jun 23, 2017 at 05:59 PM
Old discussion. I actually referred to this discussion, while trying to solve issue where I was unable to activate an inactive gameobject from the update function. I think several people have explained why this can be an issue. I am writing, because I finally solved this, using a solution I was unable to find anywhere else. so, just in case any one else encounters similar issue: I believe I was unable to activate the deactivated gameobject because I started the script with the object deactivated (unchecked). I think this meant that the object was not being found in the Start function and it certainly would not activate in the Update function.
I solved this by starting with the gameobject ACTIVE. then I deactivated it near the beginning of the script, after the object had been found (GameObject.Find).
After this, I had no problem reactivating the game object!
The script switches between two player characters (in-game). Both characters have a "Main Camera" and a "Free Look Camera Rig" attached. cam3 & rig2 (see code below) are the two game objects I had to deactivate/reactivate, in order to successfully switch the 2 characters. Here's the code I used...
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityStandardAssets.Characters.ThirdPerson; using UnityStandardAssets.Cameras; public class CharacerSwitch : MonoBehaviour { public GameObject player1; public GameObject player2; public GameObject cam3; public GameObject cam1; public GameObject rig1; public GameObject rig2; void Start() { player2 = GameObject.Find("Player2"); player1 = GameObject.Find("Player1"); cam3 = GameObject.Find("Camera3"); cam1 = GameObject.Find("Camera1"); rig2 = GameObject.Find("FreeLookCameraRig2"); rig1 = GameObject.Find("FreeLookCameraRig"); cam3.SetActive(false); rig2.SetActive(false); cam1.tag = "MainCamera"; cam3.tag = "Camera 2"; } void Update() { if (Input.GetKeyDown(KeyCode.O)) //"O" for "Other" or "Other Player" { if (player1.GetComponent<CapsuleCollider>().enabled == true) //collider arbitrary, but reflects object state { player1.GetComponent<Rigidbody>().isKinematic = true; player2.GetComponent<Rigidbody>().isKinematic = false; player1.GetComponent<CapsuleCollider>().enabled = false; player2.GetComponent<CapsuleCollider>().enabled = true; player1.GetComponent<ThirdPersonCharacter>().enabled = false; player1.GetComponent<ThirdPersonUserControl>().enabled = false; player2.GetComponent<ThirdPersonCharacter>().enabled = true; player2.GetComponent<ThirdPersonUserControl>().enabled = true; cam1.SetActive(false); rig1.SetActive(false); cam3.SetActive(true); rig2.SetActive(true); cam1.tag = "Camera 2"; cam3.tag = "MainCamera"; } } if (Input.GetKeyDown(KeyCode.P)) //"P" for "Player" { if (player1.GetComponent<CapsuleCollider>().enabled == false) //collider arbitrary, but reflects object state { player1.GetComponent<Rigidbody>().isKinematic = false; player2.GetComponent<Rigidbody>().isKinematic = true; player1.GetComponent<CapsuleCollider>().enabled = true; player2.GetComponent<CapsuleCollider>().enabled = false; player1.GetComponent<ThirdPersonCharacter>().enabled = true; player1.GetComponent<ThirdPersonUserControl>().enabled = true; player2.GetComponent<ThirdPersonCharacter>().enabled = false; player2.GetComponent<ThirdPersonUserControl>().enabled = false; cam1.SetActive(true); rig1.SetActive(true); cam3.tag = "Camera 2"; cam1 = GameObject.Find("Camera1"); cam1.tag = "MainCamera"; cam3.SetActive(false); rig2.SetActive(false); } } } }
Sorry! Obviously added code wrong! How do I properly add. Thought I just had to paste, where it said enter code here
!
Answer by virgilcwyile · Jul 03, 2017 at 06:28 PM
I guess you must be using the same script file in someplace else. That must have caused an issue. Just found same for mine.
Your answer
Follow this Question
Related Questions
SetActive between gameobjects 1 Answer
NullReferenceException when using gameObject.SetActive(false); 0 Answers
How do I fix my code so that these If statements turn an object off or on depending on a number 2 Answers
Checking a gameObject active in hierarchy not working. 1 Answer
How to get all GameObjects in a Scene, including inactive GameObjects? 0 Answers