I have objects that have children, some of those children are on different layers
I need to know:
How to temporarily store the layer of each child object, regardless of how many nested children there may be
Then change their layer
Then be able to change each child’s layer back to their original layer
When I try “GetComponentsInChildren(true).Select” I get an error that Transform[ ] does not contain definition for Select. I’m not sure what’s missing, as I haven’t yet had to work much with arrays, so I haven’t encountered an issue similar to this and have no idea how to correct it.
But am interested to try your solution since I have been looking for a solution for a couple days and every solution I try seems to only change the layers of the first one or two children. I even tried solutions that don’t bother keeping track of the original layer, yet still only the first two objects’ layers want to change for some reason
I usually find methods similar to
public static void SetLayerRecursively(this GameObject obj, int layer) {
obj.layer = layer;
foreach (Transform child in obj.transform) {
child.gameObject.SetLayerRecursively(layer);
}
}
or
public static void SetLayerRecursively(this Transform parent, int layer)
{
parent.gameObject.layer = layer;
for (int i = 0, count = parent.childCount; i < count; i++)
{
parent.GetChild(i).SetLayerRecursively(layer);
}
}
Yet still only the first two game object (I believe the parent, one child, then maybe one of it’s children) change layers. What am I missing?
Note: I don’t even have any other script that changes any layers whatsoever in my project, so there shouldn’t be any chance of another script interfering with the layer change
Take advantage of your IDE; in many cases it is smart enough to not only tell you what the issue is, but to also fix the issue for you automatically.
In this case the issue was that Select is an extension method in the System.Linq namespace, so you need to add using System.Linq; to the top of your file to import the extension method so that you can reference it in your class
Both of the SetLayerRecursively extension methods you posted should work perfectly. You can do a simple test scene that contains nothing else than test component using SetLayerRecursively to verify that this is the case (reducing the number of moving pieces like this can help a lot when debugging issues). The issues you’re having must be related to something else rather than the code in SetLayerRecursively.
And the Linq code I posted is basically just a more succinct way of expressing this:
using System.Collections.Generic;
using UnityEngine;
public static class GameObjectExtensions
{
public static void SetLayerRecursively(this GameObject @this, int layer)
{
var children = @this.GetComponentsInChildren<Transform>(true);
var originalLayers = new List<int>(children.Length);
foreach(var child in children)
{
var gameObject = child.gameObject;
originalLayers.Add(gameObject.layer);
}
// change layer
foreach(var child in children)
{
var gameObject = child.gameObject;
gameObject.layer = layer;
}
// restore layer
for(int i = 0, count = children.Length; i < count; i++)
{
Transform child = children[i];
var gameObject = child.gameObject;
gameObject.layer = originalLayers[i];
}
}
}