C#
Unity

【Unity】Editor拡張でスクリプトの名前を入れてリフレクションしようとしたらうまく行かなかった話

Editor拡張で自分で作成したスクリプトの情報を表示したい機会があって、一つ一つtypeofしてリフレクションで受け取るより名前を渡してリフレクションするほうが楽だよな~と思ってこんな感じのクラスを

namespace Assets.Scripts
{
   public class TestType : MonoBehaviour
   {
     ...
   }
}
Type type = Type.GetType("TestType"); 

で取得してみようとやってみたらnullが返ってきてあれ?と思い調べてたら解決に時間がかかってしまったので忘備録も含めて記事にしてみました。

名前空間も入れないといけない

文字列でGetTypeする場合、クラスに名前空間があったらその名前空間も入れないとnullが返ってくるみたいです。
・参考にしたサイト様(http://blog.hiros-dot.net/?p=5520)

今回リフレクションしようと思ったスクリプトは名前空間も含まれていたので、

Type type = Type.GetType("Assets.Scripts.TestType"); 

こんな感じに入れてみましたが、またもやnullが返ってきました…。

Assemblyを読み込まないといけない

調べていくとStackOverFlowに同じような現象が起きている投稿がありました。

URL:https://ja.stackoverflow.com/questions/1552/type-gettypestring%E3%81%AE%E5%B8%B0%E3%82%8A%E5%80%A4%E3%81%8Cnull%E3%81%AB%E3%81%AA%E3%82%8B

ここを見ると対応してるAssemblyからもGetTypeで型を取得できるみたいです。
なのでまず何のアセンブリがあるのか見てみることにしました。

var currentAssembly = Assembly.GetExecutingAssembly();
var referenceAssembly = currentAssembly.GetReferencedAssemblies();

GetExecutingAssemblyで現在のアセンブリの情報を取得できて、見てみると

Assembly-CSharp-Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

と表示されて、Editorのプロジェクトで使われているのがわかりました。
では今回自分が使おうとしているスクリプトはどのAssemblyなのか、Typeクラスを使って見てみました。

string assemblyName = typeof(TestType).Assembly.FullName;
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

UnityEditorのプロジェクトと自分が作ったスクリプトのプロジェクトは別物なので、GetTypeで読み込めなかったわけですね。なので最終的にこういう形になりました。

var assembly = Assembly.Load("Assembly-CSharp");
type = assembly.GetType("Assets.Scripts.TestType");

うまく読み込めてほっとしました。