# How to SetActive or enable a Canvas attached to prefabs that get instantiated (tower defense style)?

I am back again after making much progress in quest for unity and c# knowledge. I have become stumped yet again by how to enable a canvas that is attached to my prefab. Here is the situation:

I am using C# on unity 5.5.0f3.

I have UI buttons that instantiate a defense based on a prefab. That prefab has a Canvas attached to it which has a health bar attached to it. Currently, the canvas is disabled so that the health bar does not show at all times. I am trying to make it appear only when I hold down a button, in this case "Z", and disappear when I release Z. My code is letting this work if I place a prefab before hand and set the GameObject reference in the editor. I want to get it to work for any object that has this canvas attached to it. This code does not work for all of the prefabs even if I take the canvas from the prefab and make it the reference.

I have tried to use an array like I have with other things that are currently working, but it does not work the same.

Here is my code:

public class DefenseHealthToggle : MonoBehaviour
{
public GameObject defenseHealthBars;
private bool isShowing;

void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
isShowing = !isShowing;
defenseHealthBars.SetActive(isShowing);
}

if (Input.GetKeyUp(KeyCode.Z))
{
isShowing = false;
defenseHealthBars.SetActive(isShowing);
}
}
}


While this is a minor detail in the game, I am trying to not let any of the ideas go if it is because I could just not figure out how to do it. I think I will learn the most if I don't give up every time I hit a wall and so far it has improved my knowledge tremendously! Anyone point me in the right direction or help me with some code? Thank you for your time!

You can leave the Canvas or object active initially and grab it using transform.find("nameofobject") in the start.

Then you can set active or inactive whenever you want. using defenseHealthBars.SetActive(true);

public class DefenseHealthToggle : MonoBehaviour
{
private GameObject defenseHealthBars;
private bool isShowing;

void Start(){
defenseHealthBars = transform.Find("NameofObject").gameObject as GameObject;
defenseHealthBars.SetActive(false);
}

void Update()
{
if (Input.GetKeyUp(KeyCode.Z))
{
ToggleHealthBars();
}
}
void ToggleHealthBars()
{
defenseHealthBars.SetActive(!defenseHealthBars.activeSelf);
}

• Thank you! this worked wonderfully! Is it bad to have my key in my code set in the update area? I read that using GameObject.Find is not always advised. Is this the optimal way of doing it by setting it in the start function? I am just curious if my update will keep calling it and hurting performance when my scene is full of these objects. Is it better to maybe make a method of something like void ShowHealthBars () { "put my code for SetActive here" } and then have it be called when I press the key like if(Input.GetKeyDown(KeyCode.Z)) {ShowHealthBars (); } ? Thanks. – MjercerGameDev Aug 6 '17 at 23:05
• Yes that would be how I would do it. Except I would do GetKeyUp(KeyCode Z) then in your method you can just check if it is already active with .activeSelf and if it is then toggle off and if false then toggle on. I'll update the answer with a example. – Justin Markwell Aug 7 '17 at 15:38

I suggest you to automate the procedure like doing the following:

• Instead of having defenseHealtBars as public, make it private, you can use [SerializeField] if you want to have it visible in the editor anyways.
• Find the relevant canvas component (with GetComponent() or GetComponentInChildren(), depends where you placed the canvas object) in the DefenseHealthToggle script's void Start() method.
• Log an error if the script cannot find the object you want to control (enable/disable).

Also do not forget to type using UnityEngine.UI;

• Thank You for the input. I couldn't figure out quite how to do it this way on my own. It seems similar to what I was trying but failing at implementing. – MjercerGameDev Aug 6 '17 at 23:03