方針
エディタの「AddComponent」のプログラムを参考に、アタッチ可能な(ゲームオブジェクトに付けられる)すべてのコンポーネントを取得したいと思います。
参考
UnityのAddComponentについて調べてみた - Qiita
AddComponentできるのはMonoBehaviourクラスを継承しているコンポーネントだけ。MonoBehaviourはBehaviourクラス->Componentクラス->Unity…
コード
using UnityEngine;
using System.Collections.Generic;
using System;
using UnityEditor;
using System.Text.RegularExpressions;
using System.Reflection;
internal static class Sample
{
[MenuItem("Tools/LogAllComponents")]
private static void LogAllComponents()
{
foreach(var type in GetComponentTypes())
{
Debug.Log(type);
}
}
private static List<Type> GetComponentTypes()
{
var types = new List<Type>();
//すべてのコンポーネントのIDを取得する
var idArray = Unsupported.GetSubmenusCommands("Component");
//数字だけの文字列を表す正規表現
var regex = new Regex("^\\d+$");
foreach (var commandString in idArray)
{
Type type = null;
//UnityEngineのクラス以外
if (commandString.StartsWith("SCRIPT"))
{
//インスタンスIDから型を取得する
var instanceID = int.Parse(commandString.Substring(6));
var obj = EditorUtility.InstanceIDToObject(instanceID);
var monoScript = obj as MonoScript;
type = monoScript.GetClass();
}
//UnityEngineのクラス
else if (regex.IsMatch(commandString))
{
//クラスIDから型を取得する
var classID = int.Parse(commandString);
type = GetTypeByClassID(classID);
}
if (type != null)
{
types.Add(type);
}
}
return types;
}
private static Type GetTypeByClassID(int classID)
{
//"UnityType"クラスを取得する(internalなクラスである)
//以下のURLからプログラムが見れる
//https://github.com/Unity-Technologies/UnityCsReference/blob/61f92bd79ae862c4465d35270f9d1d57befd1761/Editor/Mono/TypeSystem/UnityType.cs
var unityType = Assembly.GetAssembly(typeof(MonoScript)).GetType("UnityEditor.UnityType") ;
//"FindTypeByPersistentTypeID"メソッドよりClassIDからUnityTypeを取得する
var classObject = unityType.InvokeMember("FindTypeByPersistentTypeID", BindingFlags.InvokeMethod, null, null, new object[] { classID });
if (classObject == null)
{
return null;
}
//実際の型の名前は"name"プロパティから取得できる
var name = unityType.GetProperty("name").GetValue(classObject) as string;
//すべてのアセンブリから名前が一致する型を探す
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in assembly.GetTypes())
{
if (name == type.Name)
{
return type;
}
}
}
return null;
}
}
実行結果
UnityEngine.MeshFilter
UnityEngine.TextMesh
UnityEngine.MeshRenderer
UnityEngine.SkinnedMeshRenderer
<以下略>
留意点
この方法はエディタ専用です。ランタイムでは動きません。
参考
https://gist.github.com/hecres/f594add4b38493fcf2f17317f3c88d32
※上のリンクのプログラムはスペルミスがあるので注意。
× “FindTypeByP re sistentTypeID”
〇 “FindTypeByP er sistentTypeID”
UnityのAddComponentについて調べてみた - Qiita
AddComponentできるのはMonoBehaviourクラスを継承しているコンポーネントだけ。MonoBehaviourはBehaviourクラス->Componentクラス->Unity…
コメント