button to show hide objects

Hi all,
I have a scene with 5 different objects (A-E) and 5 buttons (1-5). When the user clicks button 1, I want to hide everything and make object A visible. When the user clicks button 2 I want to hide everything and make object B visible.

I think i’m supposed to be using renderer.enable however, I’m confused with the syntax/method of referencing objects in my scene. Am I supposed to be referencing the camera in the script or just referencing the GameObject I want to make visible/hide?

Any help is appreciated.
thanks,
daniel[/code]

You should probably reference the renderers. Something like:

var obj1 : Renderer;
var obj2 : Renderer;
var obj3 : Renderer;

function OnGUI ()
{
     if (GUILayout.Button ("Object 1"))
     {
          obj1.enabled = true;
          obj2.enabled = false;
          obj3.enabled = false;
     }
}

Hi,
Thanks for the help. I created a similar setup to what you mentioned. I forgot to mention that my 5 different objects have a lot of children that I want to activate at the same time. The parent is essentially just a null object (without a mesh renderer). There are several hundred children per parent object. This changes things right?
:?
d

The easiest way would be to use SetActiveRecursively(). That does (as the name implies) set things as active or inactive, rather than just turning renderers off, but might still work depending on your setup. i.e., if the objects don’t have scripts running or anything.

BTW, having several hundred children per parent and five parents is an awful lot of objects. A lot of computers will choke on a scene like that.

–Eric

Hi Eric,
Thanks for the help. Here’s my code. It’s not working and I’m still flummoxed at the syntax of things (although I really am trying :sweat_smile: )

var Producer : GameObject;
var Prodr : Renderer;

function OnGUI () {
if (GUI.Button (Rect (33,100,192,144), "", ProducerButton))
Prodr.enabled.SetActiveRecursively(true) = Producer;
}

When I run this, I get a message saying “The variable Prod of GUI_Buttons” has not been assigned. This happened in the game object “GUI_Objects”." When I try to assign the variable in the inspector, the object doesn’t show up in the drop down list. I think this is because it doesn’t contain a mesh renderer (its only a null object). arghh.

Also, re: all the children in the parent objects, the piece won’t be distributed. It would run on a standalone machine for a presentation, etc. (lots or RAM, etc.)
thanks!
d

Since it’s dealing with turning the objects themselves on and off, you don’t need to bother with renderers (everything gets turned on/off, including the renderer).

var Producer : GameObject;

function OnGUI () {
   if (GUI.Button (Rect (33,100,192,144), "", ProducerButton))
      Producer.SetActiveRecursively(true);
}

Even when running on a specific machine, you might still want to look into ways of optimizing, like using the CombineChildren script if you can.

–Eric

hmm…

If I try

var Producer : GameObject;

function OnGUI () {
   if (GUI.Button (Rect (33,100,192,144), "", ProducerButton))
      Producer.SetActiveRecursively(true);
}

I get a message saying “Prefab GameObject’s can not be made active!”

any ideas?
thanks!d

You want to drag in an object from the scene, not the prefab itself.

–Eric

Hi,
Thanks for the help. So I dragged the respective objects from the heirarchy menu into the inspector window. Here’s my code:

//show gui in edit mode
@script ExecuteInEditMode

var blckbox : GUIStyle;
var appBug : GUIStyle;

var SSGButton : GUIStyle;
var AGSButton : GUIStyle;
var nextButton : GUIStyle;
var prevButton : GUIStyle;

var product1Button : GUIStyle;
var product2Button : GUIStyle;
var product3Button : GUIStyle;
var product4Button : GUIStyle;
var product5Button : GUIStyle;

var product1 : GameObject;
var product4 : GameObject;
var product2 : GameObject;
var product3 : GameObject;
var product5 : GameObject;

function OnGUI () {
	GUI.matrix = Matrix4x4.TRS (Vector3(0,0,0), Quaternion.identity, Vector3 (Screen.width / 1600.0, Screen.height / 1200.0, 1/1)); 

GUI.Box (Rect (0,0,260,1500), "", blckbox);

GUI.Box (Rect (33,0,130,59), "",appBug);
	//if (GUI.Button (Rect (543,17,193,37), "SSGButton", SSGButton)) print ("SSG");
	
	//if (GUI.Button (Rect (754,17,193,37), "AGSButton", AGSButton)) print ("AGS");
	
	//	if (GUI.Button (Rect (754,182,193,37), "", nextButton)) print ("NEXT");
	
	//	if (GUI.Button (Rect (543,182,193,37), "", prevButton)) print ("PREVIOUS");

if (GUI.Button (Rect (33,100,192,144), "", product1Button))  print ("product1");
	
	product1.SetActiveRecursively(true);
    product2.SetActiveRecursively(false);
    product3.SetActiveRecursively(false);
    product4.SetActiveRecursively(false);  
    product5.SetActiveRecursively(false);
      	 
if (GUI.Button (Rect (33,300,192,144), "", product2Button))print ("product2");
	product1.SetActiveRecursively(false);
    product2.SetActiveRecursively(true);
    product3.SetActiveRecursively(false);
    product4.SetActiveRecursively(false);  
    product5.SetActiveRecursively(false);

	
if (GUI.Button (Rect (33,500,192,144), "", product3Button)) print ("product3");
	product1.SetActiveRecursively(false);
    product2.SetActiveRecursively(false);
    product3.SetActiveRecursively(true);
    product4.SetActiveRecursively(false);  
    product5.SetActiveRecursively(false);
	
if (GUI.Button (Rect (33,700,192,144), "", AeraButton)) print ("product4");
	product1.SetActiveRecursively(false);
    product2.SetActiveRecursively(false);
    product3.SetActiveRecursively(false);
    product4.SetActiveRecursively(true);  
    product5.SetActiveRecursively(false);
    
if (GUI.Button (Rect (33,900,192,144), "", product5Button)) print ("product5");
	product1.SetActiveRecursively(false);
    product2.SetActiveRecursively(false);
    product3.SetActiveRecursively(false);
    product4.SetActiveRecursively(false);  
    product5.SetActiveRecursively(true);

}

However, when I press play, it loads product 5 automatically and there’s no button functionality. do I not want to use the SetActiveRecursively command for each button? I thought the purpose of this command was to set the target gameobject to be active (if true) and inactive (if false). many thanks!
d

You need to include braces for your “if” statements…without braces, only the first statement is included. The other statements are outside “if” statement and are always executed. (It’s a matter of style, but personally I use braces 100% of the time even if there’s just one statement, for the sake of consistency, and if I expand the number of statements past one, the braces are already there and I don’t have to remember to add them.)

if (GUI.Button (Rect (33,100,192,144), "", product1Button)) {
	print ("product1");
	product1.SetActiveRecursively(true); 
	product2.SetActiveRecursively(false); 
	product3.SetActiveRecursively(false); 
	product4.SetActiveRecursively(false);  
	product5.SetActiveRecursively(false);
}

Also all your product buttons have the same rect.

–Eric

Normally, they would be defined in code. But since Unity is an IDE, one can just type a variable, and then edit it in the GUI. This is fantastic when reusing scripts.
For example, having a

var thing : Transform;

allows a transform (basically an object/prefab) to be selected in the inspector. A faster way is to just drag the object in question into the slot. This method also works with things like Materials, Textures, GameObjects, etc. Just make sure it’s from the scene, not the project (unless you want to alter something globally).

I would also suggest using arrays as apposed to hardcoding everything. Why? Try adding another object to both our scripts and it should become obvious. This script does what you want, but with far less typing and far more flexibility.

// Store all objects in an inspector editable array
// The array makes it easy to process the objects
var objects : Transform[]; 

function OnGUI ()
{
	// Don't ask, I just like horizontal buttons
	GUILayout.BeginHorizontal();
	
	// loop through our array, using i for an index
	for(i = 0; i < objects.length; i++)
	{
		// Get the object name, makes for nicer buttons
		var objName = objects[i].name;
		
		// The GUI code goes here. I'm using GUILayout for convience
		if(GUILayout.Button(objName))
		{
			Cloak(i); // Call the "Cloak" function. See below
		}
	}
	
	// Ending the horizontal layout
	GUILayout.EndHorizontal(); 
}

// This handles the actual activation/deactivation of the objects
// Remember, this runs all in less than a frame, so only the final result is visible 
function Cloak (index) 
{
	// Loop through all objects, setting their (and any of their children's) active to false
	for(obj in objects)
	{
		obj.gameObject.SetActiveRecursively(false);
	}
	
	// Activate the ONE we want on
	objects[index].gameObject.SetActiveRecursively(true);
}

Hope it helps :stuck_out_tongue:

thanks so much! Both options seem to work out. I kinda thought that’s how array’s worked but am still learning as I go. :sweat_smile:

Thanks again for the help!
d