Foreach with GameObject.Find()

Whenever I click on a button that’s supposed to switch between one of six panels that contain their own series of buttons using UnityUI, I get the following error:

NullReferenceException: Object
reference not set to an instance of an
object button_selectedC.CanvasReset ()
(at
Assets/Scripts/button_selectedC.cs:25)

I’ve been trying to get this to work for hours, but cannot figure out what I’m doing wrong.

If I use Debug.Log(name); , the strings stored in the array pop up as I expect them to.

void Start(){
	panelNames[0] = "Panel_mapButtons";
	panelNames[1] = "Panel_inventoryButtons";
    panelNames[2] = "Panel_characterButtons";
    panelNames[3] = "Panel_shipButtons";
    panelNames[4] = "Panel_recordsButtons";
    panelNames[5] = "Panel_unknownButtons";

	}

	void CanvasReset (){
		foreach(string name in panelNames){
			Debug.Log (name);
			GameObject.Find (name).GetComponent<CanvasGroup>().alpha = 0;
			GameObject.Find (name).GetComponent<CanvasGroup>().interactable = false;
			GameObject.Find (name).GetComponent<CanvasGroup>().blocksRaycasts = false;
		}
	}

CanvasReset() is called whenever one of the buttons that switches between the panels is clicked.

Clearly, I would advise you to use a public array of GameObjects and drag & drop your objects into it. There are multiple advantages :

  • It’s far more flexible. If you want to change the name, the position in the hierarchy, add or remove an object, you don’t have to do it in your code
  • You don’t have to deal with GameObject.Find which is a CPU-intensive function and it’s a source of problems like now

If you still want to use the GameObject.Find method, make sure your objects are active in the hierarchy (parent + themselves). Also, if you can give a “path” from the root “node” of the hierarchy or from your transform, it could solve your problem.