An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
3.6 KiB

// This code is part of the Fungus library (https://github.com/snozbot/fungus)
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace Fungus.EditorUtils
{
public static class EditorExtensions
{
/// <summary>
/// FindDerivedTypesFromAssembly allows a user to query all of types derived from a
/// particular Type at runtime.
/// Example usage:
/// foreach (System.Type st in EditorUtility.FindDerivedTypesFromAssembly(System.Reflection.Assembly.GetAssembly(typeof(BaseTimelineEvent)), typeof(BaseTimelineEvent), true))
/// </summary>
/// <param name="assembly">The assembly to search in</param>
/// <param name="baseType">The base Type from which all returned Types derive</param>
/// <param name="classOnly">If true, only class Types will be returned</param>
/// <returns></returns>
public static System.Type[] FindDerivedTypesFromAssembly(this System.Reflection.Assembly assembly, System.Type baseType, bool classOnly = true)
{
if (assembly == null)
Debug.LogError("Assembly must be defined");
if (baseType == null)
Debug.LogError("Base type must be defined");
// Iterate through all available types in the assembly
var types = assembly.GetTypes().Where(type =>
{
if (classOnly && !type.IsClass)
return false;
if (baseType.IsInterface)
{
var it = type.GetInterface(baseType.FullName);
if (it != null)
return true;
}
else if (type.IsSubclassOf(baseType))
{
return true;
}
return false;
}
);
return types.ToArray();
}
/// <summary>
/// A convenient method for calling the above, but for ALL assemblies.
/// Example usage:
/// List<System.Type> subTypes = EditorUtility.FindDerivedTypes(typeof(BaseTimelineEvent)).ToList();
/// </summary>
/// <param name="baseType"></param>
/// <param name="classOnly"></param>
/// <returns></returns>
public static System.Type[] FindDerivedTypes(System.Type baseType, bool classOnly = true)
{
#if UNITY_2019_2_OR_NEWER
var results = TypeCache.GetTypesDerivedFrom(baseType).ToArray();
if (classOnly)
return results.Where(x => x.IsClass).ToArray();
else
return results.ToArray();
#else
System.Type[] typeArray = new System.Type[0];
var retval = typeArray.Concat(typeArray);
foreach (var assem in System.AppDomain.CurrentDomain.GetAssemblies())
{
retval = retval.Concat(FindDerivedTypesFromAssembly(assem, baseType, classOnly));
}
return retval.ToArray();
#endif
}
/// <summary>
/// Find and return all Unity.Objects that have the target interface
/// </summary>
/// <typeparam name="T">Intended to be an interface but will work for any</typeparam>
/// <returns></returns>
public static List<T> FindObjectsOfInterface<T>()
{
return Object.FindObjectsOfType<Object>().OfType<T>().ToList();
}
}
}