はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Object.FindObjectsOfTypeを高速化したObject.FindObjectsByTypeを用いてシーン中に存在する指定された型のオブジェクトを全て列挙する

はじめに

今回はObject.FindObjectsByTypeを紹介したいと思います。

docs.unity3d.com

対応バージョン

Unity 2020.3.4 or later
Unity 2021.3.18 or later
Unity 2022.2.5 or later

概要

Object.FindObjectsByTypeシーン中に存在する指定された型のオブジェクトを全て列挙するメソッドです。

以前はObject.FindObjectsOfTypeというメソッドがありましたがObsoleteとなり、Object.FindObjectsByTypeの利用が推奨されています。

public static Object[] FindObjectsByType(Type type, FindObjectsSortMode sortMode);
public static Object[] FindObjectsByType(Type type, FindObjectsInactive findObjectsInactive, FindObjectsSortMode sortMode);
public static T[] FindObjectsByType<T>(FindObjectsSortMode sortMode);
public static T[] FindObjectsByType<T>(FindObjectsInactive findObjectsInactive, FindObjectsSortMode sortMode);

パラメーターは以下の通り。

パラメーター名 意味
type 探すオブジェクトのType
findObjectsInactive アクティブでないGameObjectにアタッチされているコンポーネントを含めるかどうか。デフォルトはFindObjectInactive.Excludeで、アクティブでないものは含めない
sortMode InstanceIDでソートするかどうか。ソートしないと高速に動作する。Object.FindObjectsOfTypeと動作を同じにしたい場合はFindObjectsSortMode.InstanceIDを指定する

返り値は指定されたTypeに一致するオブジェクトの配列です。

それぞれの列挙型の定義は以下の通り。

namespace UnityEngine
{
  /// <summary>
  ///   <para>Options to control whether object find functions return inactive objects.</para>
  /// </summary>
  public enum FindObjectsInactive
  {
    /// <summary>
    ///   <para>Don't include inactive objects in the array of objects that the function returns.</para>
    /// </summary>
    Exclude,
    /// <summary>
    ///   <para>Include inactive objects in the array of objects that the function returns.</para>
    /// </summary>
    Include,
  }
}
namespace UnityEngine
{
  /// <summary>
  ///   <para>Options to specify if and how to sort objects returned by a function.</para>
  /// </summary>
  public enum FindObjectsSortMode
  {
    /// <summary>
    ///   <para>Don't sort the objects.</para>
    /// </summary>
    None,
    /// <summary>
    ///   <para>Sort the objects by InstanceID in ascending order.</para>
    /// </summary>
    InstanceID,
  }
}

docs.unity3d.com

利用例

public class Sample : MonoBehaviour
{
    private void Start()
    {
        // 非アクティブなGameObjectは対象にしない、順序不定でシーン上に存在するTextMeshProUGUIコンポーネントを全て取得する
        TextMeshProUGUI[] textMeshProUGUIs1 = FindObjectsByType<TextMeshProUGUI>(FindObjectsSortMode.None);
        
        // 非アクティブなGameObjectも対象にした、InstanceIDでソートされた、全てのシーン上に存在するTextMeshProUGUIコンポーネントを取得する
        TextMeshProUGUI[] textMeshProUGUIs2 = FindObjectsByType<TextMeshProUGUI>(FindObjectsInactive.Include, FindObjectsSortMode.InstanceID);
        
        // 非アクティブなGameObjectは対象にしない、順序不定でシーン上に存在するTextMeshProUGUIコンポーネントを全て取得する
        Object[] textMeshProUGUIs3 = FindObjectsByType(typeof(TextMeshProUGUI), FindObjectsSortMode.None);
        
        // 非アクティブなGameObjectも対象にした、InstanceIDでソートされた、全てのシーン上に存在するTextMeshProUGUIコンポーネントを取得する
        Object[] textMeshProUGUIs4 = FindObjectsByType(typeof(TextMeshProUGUI),FindObjectsInactive.Include, FindObjectsSortMode.InstanceID);
    }
}