Find GameObject recursively in the Unity hierarchy with LINQ queries
How can you find GameObjects and transforms in the hierarchy? Find, FindGameObjectWithTag and FindGameObjectWithTag all have some restrictions. How cool would it be if you could write LINQ-style queries to find objects based on ANY condition you can think of? This tutorial tells you how you can do this with just a few lines of code
In a previous article, I wrote about the possible ways to find GameObjects in Unity. In the article I presented the FirstChildOrDefault
function, that finds children of a transform that match the condition you provided. One of the restrictions of this function is that it does not return when the condition is true for the root object you provide.
Here is an updated version that allows you to find GameObjects anywhere in the hierarchy. You can also find many examples here.
The code
Create a script in your project and paste this code:
using System;
using UnityEngine;
public static class TransformEx
{
public static Transform FirstOrDefault(this Transform transform, Func<Transform, bool> query)
{
if (query(transform)) {
return transform;
}
for (int i = 0; i < transform.childCount; i++)
{
var result = FirstOrDefault(transform.GetChild(i), query);
if (result != null)
{
return result;
}
}
return null;
}
}
Examples
Find transform by name
Main Camera
Directional Light
a
+-b
+-c
+-d
Script attached to a
:
Debug.Log(transform.FirstOrDefault(x => x.name == "d").name);
Output:
d
Find where transform has more than 1 child
Main Camera
Directional Light
a
+-b
+-c
+-d
+-e
Script attached to a
:
Debug.Log(transform.FirstOrDefault(x => x.childCount > 1).name);
Output:
c
Find first object that has a rigidbody attached
Main Camera
Directional Light
a
+-b (has rigidbody attached)
+-c
+-d
+-e
Script attached to a
:
Debug.Log(transform.FirstOrDefault(x => x.GetComponent<Rigidbody>() != null).name);
Output:
b
Find first active object
Active elements in the hierarchy:
a
+-b
+-c
Script attached to a
:
Debug.Log(transform.FirstOrDefault(x => x.gameObject.activeInHierarchy).name);
Output:
a
Find first object where position.x > 5
Main Camera
Directional Light
a
+-b
+-c
+-d
+-e (position.x = 10)
Script attached to a
:
Debug.Log(transform.FirstOrDefault(x => x.position.x > 5).name);
Output:
e