Skip to content

Instantly share code, notes, and snippets.

@Rovsau
Last active July 14, 2023 13:20
Show Gist options
  • Save Rovsau/5d06ff262679f9be6e2fbcb18c4eb74e to your computer and use it in GitHub Desktop.
Save Rovsau/5d06ff262679f9be6e2fbcb18c4eb74e to your computer and use it in GitHub Desktop.

Untested structure to facilitate using void Reset() for getting components.

  • Interface
  • Implementation - MonoBehaviour
  • Implementation - ScriptableObject
  • Static Methods
  • Abstract MonoBehaviour
  • Abstract ScriptableObject

Interface

public interface IHasComponents
{
    public void GetComponents();
}

Implementation - MonoBehaviour

public class MyScript : MonoBehaviour, IHasComponents
{
    [SerializeField] private Transform _transform;
    public void GetComponents()
    {
        _transform = this.transform;
    }
    private void Reset()
    {
        GetComponents();
    }
}

Implementation - ScriptableObject

public class MySO : ScriptableObject, IHasComponents
{
    [SerializeField] private Transform _transform;
    public void GetComponents()
    {
        _transform = GameObject.Find("some name").transform;
    }
    private void Reset()
    {
        GetComponents();
    }
}

Static Methods

public static class InterfaceHelper
{
    public static void RunAll_IHasComponents_GetComponents()
    {
        foreach (var behaviour in FindLoadedMembersOfInterface<IHasComponents>())
        {
            try
            {
                behaviour.GetComponents();
            }
            catch (System.Exception exception)
            {
                Debug.LogError(exception.Message);
            }
        }
    }
    public static List<T> FindLoadedMembersOfInterface<T>(bool includeScriptableObjects = true)
    {
        var found = new List<T>();
        foreach (var monoBehaviour in Resources.FindObjectsOfTypeAll<MonoBehaviour>())
        {
            if (monoBehaviour is T behaviour)
            {
                found.Add(behaviour);
            }
        }
        if (includeScriptableObjects)
        {
            foreach (var scriptableObject in Resources.FindObjectsOfTypeAll<ScriptableObject>())
            {
                if (scriptableObject is T behaviour)
                {
                    found.Add(behaviour);
                }
            } 
        }
        return found;
    }
}

Abstract MonoBehaviour

public abstract class ComponentBehaviour : MonoBehaviour
{
    private protected virtual void Reset()
    {
        GetComponents();
    }
    private protected virtual void GetComponents()
    {
        throw new System.NotImplementedException();
    }
    private static void AllMembersGetComponents()
    {
        foreach (var behaviour in Object.FindObjectsOfType<ComponentBehaviour>())
        {
            try
            {
                behaviour.GetComponents();
            }
            catch (System.Exception exception)
            {
                Debug.LogError(exception.Message);
            }
        }
    }
}
#if UNITY_EDITOR
    [UnityEditor.MenuItem("Tools / " + nameof(ComponentBehaviour) + " / Get Components for Loaded Members")]
    private static void MenuItemAllMembersGetComponents()
    {
        if (EditorUtility.DisplayDialog("Confirmation", "Are you sure you want to get all components " +
                "for all Loaded members of type " + nameof(ComponentBehaviour) + "?", "Yes", "Cancel"))
        {
            AllMembersGetComponents();
        }
    }
#endif

Abstract ScriptableObject

Uses Resources.FindObjectsOfTypeAll<T>() which finds all project objects, including assets and inactive objects. It is slow, but the benefit is that the ScriptableObject assets don't need to be inside a Resources folder.

public abstract class ComponentObject : ScriptableObject
{
    private protected virtual void Reset()
    {
        GetComponents();
    }
    private protected virtual void GetComponents()
    {
        throw new System.NotImplementedException();
    }
    private static void AllMembersGetComponents(ComponentObject[] componentObjects = null)
    {
        if (componentObjects == null) componentObjects = Resources.FindObjectsOfTypeAll<ComponentObject>();
        foreach (var behaviour in componentObjects)
        {
            try
            {
                behaviour.GetComponents();
            }
            catch (System.Exception exception)
            {
                Debug.LogError(exception.Message);
            }
        }
    }
#if UNITY_EDITOR
    [UnityEditor.MenuItem("Tools / " + nameof(ComponentObject) + " / Get Components for Loaded Members")]
    private static void MenuItemAllMembersGetComponents()
    {
        var found = Resources.FindObjectsOfTypeAll<ComponentObject>();
        if (EditorUtility.DisplayDialog("Confirmation", "Are you sure you want to get all components " +
            "for all Loaded members of type " + nameof(ComponentObject) + "?" + System.Environment.NewLine +
            "Found: " + found.Length + "", "Yes", "Cancel"))
        {
            AllMembersGetComponents(found);
        }
    }
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment