How can I find all objects that have a script that implements a certain interface?

And also run functions implemented from the interface?

Right now I have this:

			IStats[] ss = (IStats[])FindObjectsOfType (typeof(IStats));
			foreach (IStats s in ss) {
				enemies.Add (s);
			}

Then I do this:

				foreach (IStats enemy in enemies) {
					enemy.Damage (damage, (int)element);
					enemies.Remove (enemy);
				}

But I’m getting an error when running the game:
FindAllObjectsOfType: The type has to be derived from UnityEngine.Object. Type is IStats.
UnityEngine.Object:FindObjectsOfType(Type)
Projectiles.c__Iterator3:MoveNext() (at Assets/Scripts/Projectiles/DemonStar.cs:25)

These answers are unnecessarily complex. Just use LINQ.

using System.Linq;   
...    
             var ss = FindObjectsOfType<MonoBehaviour>().OfType<IStats>();
             foreach (IStats s in ss) {
                 enemies.Add (s);
             }

If you’re looking for something that isn’t a subclass of MonoBehaviour, then just broaden the search by replacing MonoBehaviour in the snippet above with Behaviour, Component, or Object.

Here is my solution.

  1. Get all root GameObjects in scene
  2. Use GetComponentsInChildren on each (it works with Interfaces)
  3. Return list of interfaces found

Here’s the code:

Gist: FindInterfaces.cs · GitHub

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Glitchers
{
	public static class FindInterfaces
	{
		public static List<T> Find<T>(  )
		{
			List<T> interfaces = new List<T>();
			GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();

			foreach( var rootGameObject in rootGameObjects )
			{
				T[] childrenInterfaces = rootGameObject.GetComponentsInChildren<T>();
				foreach( var childInterface in childrenInterfaces )
				{
					interfaces.Add(childInterface);
				}
			}

			return interfaces;
		}
	}
}

I’ve thought on this problem and came up with a solution that looks for all types that implement a given interface at initialization (in a static constructor), adds them to a lookup table, and then uses that table at runtime to find required objects. This solution is almost as fast as Unity’s built-in FindObjectsOfType() method.

Here’s the link: Interface Finder

Usage example:

var stuff = InterfaceHelper.FindObject<IIrresistible>();
var component = transform.GetInterfaceComponent<IIrresistible>();

This should do the trick to find a single object.

    public static T FindOfType<T>() where T : class {
        foreach(var monoBehaviour in GameObject.FindObjectsOfType<MonoBehaviour>()) {
            if (monoBehaviour is T) {
                return monoBehaviour as T;
            }
        }
        return default(T);
    }

A bit of an oldie, but hopefully this might help some folks out… This will return True along with references to the first found gameobject with a component that is of type T (or implements an interface of type T), or False if not found in the active scene.

public static bool TryFindGameObjectWithType<T>(ref GameObject foundGameObject, ref T foundObject)
		{
			GameObject[] gos = UnityEngine.Object.FindObjectsOfType<GameObject>();
			for (int i = 0; i < gos.Length; i++) {
				if ((foundObject = gos*.transform.GetComponent<T>()) != null) {*

_ foundGameObject = gos*;_
_
return true;_
_
}_
_
}_
_
return false;_
_
}*_
Cheers, Isaac :slight_smile:

Hi,
I tried out some different versions and thought I would continue the post here.
My InterfaceService looks like this:

public static class InterfaceService
{
    public static IEnumerable<T> FindOnActiveScene<T>(bool includeInactive = false)
    {
        return SceneManager.GetActiveScene().GetRootGameObjects().SelectMany(go => go.GetComponentsInChildren<T>(includeInactive));
    }
    
    public static IEnumerable<T> FindOnAllScenes<T>(bool includeInactive = false)
    {
        return Enumerable.Range(0,SceneManager.sceneCount).SelectMany(sceneIndex => SceneManager.GetSceneAt(sceneIndex).GetRootGameObjects().SelectMany(go => go.GetComponentsInChildren<T>(includeInactive)));
    }
    
    public static IEnumerable<T> FindOnDontDestroyOnLoad<T>(bool includeInactive = false)
    {
        return DontDestroyOnLoadAccessor.GetInstance().GetRootGameObjects().SelectMany(go => go.GetComponentsInChildren<T>(includeInactive));
    }

    public static IEnumerable<T> FindGeneral<T>(bool includeInactive = false) {
        return Object.FindObjectsOfType<MonoBehaviour>(includeInactive).OfType<T>();
    }
}

With a singleton that uses DontDestroyOnLoad to get the scene of the DontDestroyOnLoad objects

public class DontDestroyOnLoadAccessor : PersistentSingleton<DontDestroyOnLoadAccessor>
{
    public GameObject[] GetRootGameObjects() {
        return this.gameObject.scene.GetRootGameObjects();
    }
}

I also ran a test to see how fast they where by running each of the 10000 times in a row.

FindOnActiveScene Execution Time: 7 ms, with count: 0
FindOnDontDestroyOnLoad Execution Time: 7 ms, with count: 3
FindGeneral Execution Time: 1386 ms, with count: 3
FindOnAllScenes Execution Time: 2 ms, with count: 0

As you can see only FindGeneral() and FindOnDontDestroyOnLoad finds the gameobjects with the interface when it has a component using DontDestroyOnLoad.

I do not know why FindOnActiveScene is so much slower than FindOnAllScenes, they should have been close since I only have one scene. Maybe the GetActiveScene() method does something slightly demanding.