Find active Child gameobject out of multiple gameobjects
I have a parent (Extras Container) with multiple child gameobjects. I want to add much more gameobjects to this later:
They're all inactive at start, but they all have their own buttons that set them to be active. However, I only want one child gameobject to be active at one time. So when one button gets pressed, all the other gameobjects should be disabled.
So what I want is: When a button is pressed, that child gameobject is active and becomes the "currentObject." All other child gameobjects become inactive. If the same button is pressed, no child gameobjects are active and no objects are the "currentObject."
I have some code that works for now, but it seems extremely inefficient for multiple gameobjects down the road. I just want to find the active child gameobject and set it as the "currentObject."
public void Update()
{
if (currentObject != null)
{
currentText.text = currentObject.name;
}
if (currentObject != cube)
{
cube.SetActive(false);
if (currentObject != null)
{
cube.transform.position = currentObject.transform.position;
}
}
if (currentObject != sphere)
{
sphere.SetActive(false);
if (currentObject != null)
{
sphere.transform.position = currentObject.transform.position;
}
}
if (currentObject != capsule)
{
capsule.SetActive(false);
if (currentObject != null)
{
capsule.transform.position = currentObject.transform.position;
}
}
if (currentObject != cylinder)
{
cylinder.SetActive(false);
if (currentObject != null)
{
cylinder.transform.position = currentObject.transform.position;
}
}
}
public void ToggleObject()
{
if (currentObject.activeSelf)
{
currentObject.transform.position = originalPos;
currentObject.SetActive(false);
}
}
// HOOKED UP TO THE BUTTONS
public void AddCube()
{
currentObject = cube;
ToggleObject();
}
public void AddSphere()
{
currentObject = sphere;
ToggleObject();
}
public void AddCapsule()
{
currentObject = capsule;
ToggleObject();
}
public void AddCylinder()
{
currentObject = cylinder;
ToggleObject();
}
}
Answer by unity_ek98vnTRplGj8Q · Feb 20, 2020 at 11:09 PM
Here is how I would go about this to make this as easy to work with for tons of children objects as possible. Instead of using separate functions for each, you can use the same function for all of them, passing in the desired index of the object you want. The only weird part is the initialization, because you have to activate all the objects to get their corresponding child indexes.
public GameObject extrasContainer;
private GameObject currentObject;
private GameObject[] childrenObjects;
void Start(){
//Loop through once to activate all children so we can correctly get their child index
foreach (Transform t in extrasContainer.GetComponentsInChildren<Transform>(true))
{
if(t.activeSelf && t.parent == extrasContainer.transform) currentObject = t.gameObject; //Save whichever one you have activated at the start
t.gameObject.SetActive(true);
}
//Loop through again to save their child indices
childrenObjects = new GameObject[extrasContainer.childCount];
foreach (Transform t in extrasContainer.GetComponentsInChildren<Transform>(true))
{
if(t.parent == extrasContainer.transform) childrenObjects[t.GetSiblingIndex()] = t;
}
//Loop through once more to deactivate the children
foreach (Transform t in extrasContainer.GetComponentsInChildren<Transform>(true))
{
if(t.gameObject != currentObject){
if(t.parent == extrasContainer.transform) t.gameObject.SetActive(false);
}
}
}
public void ChooseObject(int index){
if(index < extrasContainer.transform.childCount){
GameObject newObject = childrenObjects[index].gameObject;
if(newObject != currentObject){
if(currentObject != null) currentObject.SetActive(false);
newObject.SetActive(true);
currentObject = newObject;
}
else{
currentObject.SetActive(false);
currentObject = null;
}
}
}
So if you have your objects ordered like you do in your screenshot and you want to activate the cube, you would call ChooseObject(0);
. If you want to call this function from a button, you can set the associated index value in the inspector. The nice thing about this is that when you want to add new objects, you don't have to write any new code. Just put your new object as the last child object of the extras container, and give the corresponding button the ChooseObject callback with the index of the new object.
Hey, thanks so much for the reply and help! This way does look way more efficient for dealing with multiple gameobjects!
I tried to apply the code and I do get a few errors though.
The first error is referring to this line: if (t.activeSelf && t.parent == extrasContainer.transform) currentObject = t.gameObject;
The second is referring to this line: childrenObjects = new GameObject[extrasContainer.childCount];
And the third is referring to this line: if (t.parent == extrasContainer.transform) childrenObjects[t.GetSiblingIndex()] = t;
Yea my bad I didn't test the code -
1. Change t.activeSelf
to t.gameObject.activeSelf
2. Change extrasContainer.childCount
to extrasContainer.transform.childCount
3. Change that last t
to t.gameObject
I just got my gameobjects and transforms mixed up a couple times
Well it all works perfectly now! Wow, thanks so much for your help!
Answer by prakyathd801 · Nov 10, 2020 at 11:30 AM
if(childName.gameObject.activeSelf)
{
//Do something
}
Your answer
Follow this Question
Related Questions
Make a 3D Object look like hes facing a point in an 2D space 0 Answers
Scale of object does not update properly with public variable 1 Answer
How can I make the game object follow the mouse? 1 Answer
Collision detection in 2017 3d 4.2f2 0 Answers
Set One GameObject Inactive If Another GameObject Is Active? 1 Answer