Unityにおけるオブジェクト検索メソッドの徹底解説
Unityでは、シーン内のオブジェクトを検索するために複数のメソッドが用意されています。用途やパフォーマンス面、条件に合わせた検索など、さまざまなケースに応じて使い分ける必要があります。以下では、代表的な検索メソッドと、その応用例(タグや名前による条件抽出、スクリプトではなくGameObject自体を対象とする例)を詳細に解説します。
なお、以前よく使われた FindObjectOfType と FindObjectsOfType は、現在(Unity 6.6 / 6000.6系)では非推奨のため、本記事では後継の FindFirstObjectByType・FindAnyObjectByType・FindObjectsByType を使って解説します。

1. FindFirstObjectByType
概要
- 動作内容
指定された型の中で、最初に見つかったアクティブなロード済みオブジェクト(通常はインスタンスIDが最も低いもの)を返します。 - 特性
- 一貫性:常に同じ条件で検索されるため、結果が安定しています。
- パフォーマンス負荷:シーン内の全オブジェクトを走査するため、毎フレームの利用は避けるべきです。
- 利用シーン
シングルトンパターンなど、特定の1つのインスタンスを確実に取得する必要がある場合に適しています。 - 非アクティブオブジェクトの取り扱い
引数にFindObjectsInactive.Includeを指定することで、非アクティブなオブジェクトも対象に含められます。
サンプルコード
// アクティブなオブジェクトのみ検索(デフォルト)
OtherScript instance1 = FindFirstObjectByType<OtherScript>();
// 明示的に非アクティブなオブジェクトを除外して検索
OtherScript instance2 = FindFirstObjectByType<OtherScript>(FindObjectsInactive.Exclude);
// 非アクティブなオブジェクトも含めて検索
OtherScript instance3 = FindFirstObjectByType<OtherScript>(FindObjectsInactive.Include);
2. FindAnyObjectByType
概要
- 動作内容
指定された型のアクティブなロード済みオブジェクトのうち、任意の1つ(毎回異なる可能性がある)を返します。 - 特性
- 高速な処理:全体を走査する必要がなく、条件に合致した最初のオブジェクトを返すため効率的です。
- 結果の一貫性が低い:返されるオブジェクトは毎回変わる可能性があるため、特定のインスタンスを必要とする場合には不向きです。
- 利用シーン
パフォーマンスを重視し、どのインスタンスでも問題ない場合に利用されます。 - 非アクティブオブジェクトの取り扱い
引数により制御が可能です。
サンプルコード
// アクティブなオブジェクトのみ検索(デフォルト)
OtherScript instance1 = FindAnyObjectByType<OtherScript>();
// 明示的に非アクティブなオブジェクトを除外して検索
OtherScript instance2 = FindAnyObjectByType<OtherScript>(FindObjectsInactive.Exclude);
// 非アクティブなオブジェクトも含めて検索
OtherScript instance3 = FindAnyObjectByType<OtherScript>(FindObjectsInactive.Include);
3. FindObjectsByType:複数のオブジェクトを一括取得
概要
- 動作内容
シーン内の指定型のオブジェクトをすべて配列として取得します。旧APIのFindObjectsOfTypeに代わる、現在の書き方です。 - 特性
- 一括取得:複数のオブジェクトに対して一括で処理を行いたい場合に有効です。
- 非アクティブの扱い:
FindObjectsInactive.Exclude(含めない)/Include(含める)で指定します。 - 並べ替え:
FindObjectsSortMode.None(並べ替えない)/InstanceID(インスタンスID順)で指定します。順番が不要ならNoneにすると、不要な並べ替えを避けられます。
- パフォーマンスの注意点:シーン内のオブジェクト数が多い場合、全体を走査するため負荷が高くなる可能性があります。Update の中で毎フレーム呼ばず、Start などで一度取得して使い回しましょう。
基本サンプルコード
// アクティブなオブジェクトのみを、並べ替えずにすべて取得(基本の書き方)
OtherScript[] instances =
FindObjectsByType<OtherScript>(
FindObjectsInactive.Exclude,
FindObjectsSortMode.None);
// 非アクティブなオブジェクトも含めて取得
OtherScript[] allInstances =
FindObjectsByType<OtherScript>(
FindObjectsInactive.Include,
FindObjectsSortMode.None);
4. 条件によるフィルタリングの応用例
FindObjectsByTypeで取得した配列に対し、LINQを利用してさらに条件を絞り込む方法を紹介します。
4.1. プロパティ値でフィルタリング
たとえば、コンポーネント OtherScript に score という数値プロパティがあり、score が50以上のものを抽出する場合:
using System.Linq; // LINQ利用のために必要
// シーン内の全 OtherScript コンポーネントを取得
OtherScript[] allInstances =
FindObjectsByType<OtherScript>(
FindObjectsInactive.Exclude,
FindObjectsSortMode.None);
// score プロパティが 50 以上のオブジェクトを抽出
OtherScript[] filteredInstances = allInstances.Where(instance => instance.score >= 50).ToArray();
foreach (var instance in filteredInstances)
{
Debug.Log($"Scoreが50以上のインスタンス: {instance.name}");
}
4.2. タグを条件にフィルタリング
例2-1: LINQでタグフィルタリング
using System.Linq; // LINQ利用のために必要
// シーン内の全 OtherScript コンポーネントを取得
OtherScript[] allInstances =
FindObjectsByType<OtherScript>(
FindObjectsInactive.Exclude,
FindObjectsSortMode.None);
// タグが "Enemy" のオブジェクトを抽出
OtherScript[] enemyInstances = allInstances.Where(instance => instance.CompareTag("Enemy")).ToArray();
foreach (var enemy in enemyInstances)
{
Debug.Log($"Enemyタグが付いたインスタンス: {enemy.name}");
}
例2-2: GameObject.FindGameObjectsWithTag を利用する方法
タグ “Enemy" を持つ GameObject を直接取得し、そこから必要なコンポーネントを参照する方法です。
// タグ "Enemy" を持つ全 GameObject を取得
GameObject[] enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");
foreach (GameObject enemyObj in enemyObjects)
{
// 例として、Enemyオブジェクトに OtherScript コンポーネントが付いている場合
OtherScript script = enemyObj.GetComponent<OtherScript>();
if (script != null)
{
Debug.Log($"Enemyタグが付いたオブジェクトからOtherScriptを取得: {enemyObj.name}");
}
}
4.3. 名前を条件にフィルタリング
4.3.1. コンポーネントの名前でフィルタリング
(対象がスクリプトコンポーネントの場合)
using System.Linq; // LINQ利用のために必要
// シーン内の全 OtherScript コンポーネントを取得
OtherScript[] allInstances =
FindObjectsByType<OtherScript>(
FindObjectsInactive.Exclude,
FindObjectsSortMode.None);
// 名前が "TargetObject" のコンポーネントを抽出
OtherScript[] targetInstances = allInstances.Where(instance => instance.name == "TargetObject").ToArray();
foreach (var instance in targetInstances)
{
Debug.Log($"名前が 'TargetObject' のインスタンス: {instance.name}");
}
4.3.2. GameObject自体の名前でフィルタリング
スクリプトに依存せず、GameObjectの名前を条件に複数のオブジェクトを取得する場合の例です。
using System.Linq; // LINQ利用のために必要
using UnityEngine;
public class FindByNameExample : MonoBehaviour
{
void Start()
{
// シーン内の全アクティブなGameObjectを取得
GameObject[] allObjects =
FindObjectsByType<GameObject>(
FindObjectsInactive.Exclude,
FindObjectsSortMode.None);
// 名前が "TargetObject" と一致するGameObjectを抽出
GameObject[] targetObjects = allObjects.Where(obj => obj.name == "TargetObject").ToArray();
foreach (var obj in targetObjects)
{
Debug.Log($"名前が 'TargetObject' のGameObject: {obj.name}");
}
}
}
5. (旧バージョン)FindObjectOfType / FindObjectsOfType
概要
- 概要
以前のUnityでよく使われていたメソッドです。FindObjectOfType<T>()は最初の1件を、FindObjectsOfType<T>()は複数件を配列で返していました。 - 現在の扱い
どちらもUnity 6では非推奨です。古い記事やプロジェクトで見かけたら、次のように置き換えます。FindObjectOfType<T>()→FindFirstObjectByType<T>()(どれでもよければFindAnyObjectByType<T>())FindObjectsOfType<T>()→FindObjectsByType<T>(FindObjectsInactive.Exclude, FindObjectsSortMode.None)
6. まとめ
- 特定の1つのインスタンスを確実に取得したい場合
→ FindFirstObjectByType を利用。常に同じ条件で検索されるため、一貫性があります。 - 任意のインスタンスで十分で、パフォーマンス重視の場合
→ FindAnyObjectByType を利用。高速に検索が行えますが、結果は毎回変わる可能性があります。 - 複数のオブジェクトを一括取得したい場合
→ FindObjectsByType を利用し、必要に応じて LINQ 等でさらにフィルタリングします。基本はFindObjectsInactive.ExcludeとFindObjectsSortMode.Noneを指定します。
・プロパティ、タグ、名前といった条件でのフィルタリング例も用意されています。
・GameObject自体を条件とする場合は、FindObjectsByType<GameObject>やGameObject.FindGameObjectsWithTagを活用できます。
各メソッドは、シーンの規模や実行時のパフォーマンス、また検索対象の条件に応じた使い分けが重要です。用途に合わせた適切な検索方法を選択することで、効率的な開発が実現できます。








ディスカッション
コメント一覧
まだ、コメントがありません