- Home /
How do I alter all children of a gameobject at once?
I have a very small city for my game. The idea is that the player shoots the buildings in the city and destroys them. But, as I said, the game board is very small, and to destroy all the buildings takes mere seconds. I'd like to make it possible to destroy buildings, and make them all re-appear at the push of a button. As of right now, the buildings are not truly destroyed, but rather are deactivated, using
gameObject.SetActive(false);
In a separate script, I have
if(Input.GetKeyDown(Keycode.Return))
{
buildings.SetActive(true);
}
where "buildings" is a public gameobject. In the editor, the gameobject "buildings" is assigned as an empty gameobject containing the other buildings in my scene as children.
This solution as I have it doesn't work. I figure it is because I am disabling the buildings individually, but enabling the parent object, leaving the children untouched. My question is this. What code do I need to use (C# please!) to SetActive(true)
for all of the children of the "buildings" gameobject?
I suppose I could simply assign all of the individual buildings as their own gameobject in the script, and activate them as such
building1.Setactive(true);
building2.Setactive(true);
building3.Setactive(true);
.....
but that is kind of exhausting, especially when I expand my map to include more buildings. There must be a way to do this all at once, or at least a way more efficient than doing them all individually. Any help appreciated.
If buildings is a parent to all the other objects then you can use a foreach statement to go through each child of buildings as a Transform like so:
foreach(Transform child in buildings.transform)
{
child.gameobject.SetActive(true);
}
Thanks for the response. I added your code to $$anonymous$$e as best I could figure but I'm still really new to this. $$anonymous$$y script is as follows
using UnityEngine;
using System.Collections;
public class GameController : $$anonymous$$onoBehaviour
{
public GameObject buildings;
void Start ()
{
buildings.SetActive(true);
}
void Update ()
{
if(Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Return))
{
foreach(Transform child in buildings.transform)
{
child.gameobject.SetActive(true);
}
}
}
}
Getting the error
Assets/Scripts/GameController.cs(19,39): error CS1061: Type `UnityEngine.Transform' does not contain a definition for `gameobject' and no extension method `gameobject' of type `UnityEngine.Transform' could be found (are you missing a using directive or an assembly reference?)
Just double check your error. You are trying to access:
child.gameobject
When you should be using:
child.gameObject
Notice that the O in gameObject is capitalized.
That fixed the error. But now after I destory the buildings, and press Enter, the buildings reappear for only a second, before disappearing again. If it helps anything, here is the script I use for the buildings, shall we say, health.
using UnityEngine;
using System.Collections;
public class BuildingHealth : $$anonymous$$onoBehaviour
{
public int health = 100;
void Update ()
{
if(health <= 0)
{
gameObject.SetActive(false);
}
}
}
Answer by Thom Denick · Jan 02, 2015 at 04:45 AM
You can do this one of two ways. The easiest way is to create a public Array and assign all of your buildings to it manually. This is generally what I would do unless the building children are getting generated dynamically. If they are generated dynamically, then you would assign the GameObjects array via code.
However, based on your scenario, it sounds like this will work:
public GameObject[] buildings;
Then iterate through each of your buildings with a for loop.
for(int i = 0; i < buildings.Length; i++) {
buildings[i].SetActive(true);
}
alternatively, you can actually find/manipulate the children by doing this:
for(int i = 0; i < building.transform.childCount; i++) {
building.transform.GetChild(i).gameObject.SetActive(true);
}
**Edited to fix code error.
Hi Thom, thanks for the response. I put your code in my script as best I could figure, but I'm still pretty new to this, and don't fully comprehend the logic of all this yet. This is my script, with your code added.
using UnityEngine;
using System.Collections;
public class GameController : $$anonymous$$onoBehaviour
{
public GameObject[] buildings;
void Start ()
{
buildings.SetActive(true);
}
void Update ()
{
if(Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Return))
{
for(int i = 0; i < buildings.Length; i++)
{
buildings.SetActive(true);
}
}
}
}
I get this error:
Assets/Scripts/GameController.cs(10,27): error CS1061: Type `UnityEngine.GameObject[]' does not contain a definition for `SetActive' and no extension method `SetActive' of type `UnityEngine.GameObject[]' could be found (are you missing a using directive or an assembly reference?)
on both SetActive(true) lines.
using UnityEngine;
using System.Collections;
public class GameController : $$anonymous$$onoBehaviour
{
public GameObject[] buildings;
void Start ()
{
for(int i = 0; i < buildings.Length; i++)
{
buildings[i].SetActive(true);
}
}
void Update ()
{
if(Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Return))
{
for(int i = 0; i < buildings.Length; i++)
{
buildings[i].SetActive(true);
}
}
}
}
This puts a drop down menu called "buildings" in the editor on the script, with a space to enter text, called size. I entered 5(the number of buildings in my scene) and it created 5 spaces that I could assign the buildings to. Now, when I destroy the buildings, and press Enter, they reappear for a fraction of a second then disappear again. I'd like to code it so that, as I expand the play area, and add more buildings, I can just child all the buildings to the "buildings" game object. So for the script, I'd like to be able to just assign the "buildings" gameobject, and have the script set all of the children of that object to active again. Does this make sense? Is it possible?
This is the script I have controlling the building destruction, if it helps anything.
using UnityEngine;
using System.Collections;
public class BuildingHealth : $$anonymous$$onoBehaviour
{
public int health = 100;
void Update ()
{
if(health <= 0)
{
gameObject.SetActive(false);
}
}
}
To make a gameObject the child of another, you can do it by setting the parent, here's a rough example:
child.transform.parent = parentObject.transform
@Thom Denick upon re-reading your answer, I see that manually assigning the buildings is exactly what you said your script would require. I apologize for my misunderstanding. $$anonymous$$y problem with the buildings appearing and disappearing still remains though. @justin35f I meant making the models of the buildings children of the empty game object manually, from the inspector, not through code. Thanks though!
Your answer
Follow this Question
Related Questions
GameObjects that I deactivate are reactivated immediately 0 Answers
Multiple Cars not working 1 Answer
c# Set Active error, conflicting with other code.. 1 Answer
Panel GameObject not activating 0 Answers
SetActive(true) is not working 2 Answers