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
Written by Loek van den Ouweland on October 04, 2019. Questions regarding this artice? You can send them to the address below.