1
\$\begingroup\$

Unity has two functions, with seemingly identical purposes, for finding an object by type.

  • Object.FindObjectOfType<T>() which has been around forever.

    The first active loaded object that matches the specified type. It returns null if no Object matches the type.

    There's also an overloaded version which accepts a single boolean argument indicating whether to search inactive objects. FindObjectOfType<T>(bool includeInactive) .

  • Object.FindFirstObjectByType<T>() which I think is newer:

    Returns the first active loaded object that matches the specified type. If no object matches the specified type, returns null.

    There's also an overloaded version which accepts a single enum argument indicating whether to search inactive objects. FindFirstObjectByType<T>(FindObjectsInactive findObjectsInactive);

These functions seem to serve identical purposes, with the only difference between them being that FindFirstObjectByType()'s overload (rather pointlessly) takes an enum argument instead of a boolean argument.

What's the difference between these two functions? Why do both exist?

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I thought of the answer while typing out the question:

There is another new function, Object.FindAnyObjectByType<T>() which serves a similar purpose. While FindFirstObjectByType() returns the "first" (oldest?) object of the specified type, FindAnyObjectByType() doesn't sort in a specific order and is therefore faster.

FindFirstObjectByType() is functionally identical to FindObjectOfType(); the reason it exists with a new name is to distinguish it from FindAnyObjectByType().

\$\endgroup\$
7
  • \$\begingroup\$ Personally I think the new option, of returning 'any' rather than 'first', should have been an overload of FindObjectOfType(), rather than a new function with a different name. Oh well. \$\endgroup\$
    – Kevin
    Feb 23, 2023 at 23:02
  • \$\begingroup\$ When there's now a choice of which policy to use, naming the policy you want explicitly in the method name makes a lot of sense. Otherwise you have two very similar looking FindObjectOfType calls that do significantly different things, without any hint at the call site about that difference. \$\endgroup\$
    – DMGregory
    Feb 24, 2023 at 3:35
  • \$\begingroup\$ @DMGregory Well, if they're using enums to represent on/off states rather than booleans, they could have something like public enum SearchMode { First, Any } and the method call look like FindObjectOfType<T>(FindObjectsInactive.Include, SearchMode.Any) \$\endgroup\$
    – Kevin
    Feb 28, 2023 at 21:12
  • 1
    \$\begingroup\$ Now you've added a runtime branch to check the search mode argument if the JIT doesn't inline it, rather than a compile-time choice of overload, reducing the speed boost you got from choosing the fast method in the first place. So that's not an ideal choice for the use case this function was made to serve. \$\endgroup\$
    – DMGregory
    Feb 28, 2023 at 23:38
  • \$\begingroup\$ @DMGregory Fair enough. I use these methods very sparingly and didn't think about the fact that the performance difference will be much more significant for the developers who use these find functions liberally every frame (although I wonder if such developers will notice the new, faster function). \$\endgroup\$
    – Kevin
    Mar 6, 2023 at 19:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .