環境
Windows 10
Unity 5.6.1f1
事の発端
ある時、以下のようなEditorWindowクラスを作ったところエラーが出てしまいました。
using UnityEngine;
using UnityEditor;
public class TestEditorWindow : EditorWindow
{
[MenuItem("Tools/TestEditorWindow")]
static public void Open()
{
GetWindow<TestEditorWindow>();
}
void ShowButton()
{
}
}
なんだこれは....
エラーの意味
MSDN(https://msdn.microsoft.com/ja-jp/library/4k9x6bc0(v=vs.110).aspx) によると
parameters 配列に正しい数の引数がありません。
という意味のエラーだそうです。(TargetParameterCountException)
エラーの発生個所
スタックトレースの中に
UnityEditor.HostView.ShowGenericMenu () (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:350)
とあるので、HostView.cs の中でエラーが出ているようです。
エラー発生個所のコードを見てみる
HostView.csはDLLの中へ隠蔽されているので
下記リポジトリからUnity内部のソースコードを読んでみます。
HostView.csの中身
Unity5.6.0f3デコンパイルコードのHostView.csを読んでみるとShowButtonメソッドをリフレクション経由で呼び出している箇所がありました。
protected void ShowGenericMenu()
{
GUIStyle gUIStyle = "PaneOptions";
Rect rect = new Rect(base.position.width - gUIStyle.fixedWidth - 4f, Mathf.Floor((float)(this.background.margin.top + 20) - gUIStyle.fixedHeight), gUIStyle.fixedWidth, gUIStyle.fixedHeight);
if (EditorGUI.DropdownButton(rect, GUIContent.none, FocusType.Passive, "PaneOptions"))
{
this.PopupGenericMenu(this.m_ActualView, rect);
}
MethodInfo paneMethod = this.GetPaneMethod("ShowButton", this.m_ActualView);
if (paneMethod != null)
{
object[] parameters = new object[]
{
new Rect(base.position.width - gUIStyle.fixedWidth - 20f, Mathf.Floor((float)(this.background.margin.top + 4)), 16f, 16f)
};
paneMethod.Invoke(this.m_ActualView, parameters);
}
}
private MethodInfo GetPaneMethod(string methodName)
{
return this.GetPaneMethod(methodName, this.m_ActualView);
}
private MethodInfo GetPaneMethod(string methodName, object obj)
{
MethodInfo result;
if (obj == null)
{
result = null;
}
else
{
for (Type type = obj.GetType(); type != null; type = type.BaseType)
{
MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
引数としてRect型変数を指定してリフレクション経由でShowButtonメソッドを呼んでいるようです。
どうやら先ほどのエラーは、EditorWindow内に引数なしShowButtonメソッドを定義したことによって発生してしまっていたようです。
試しにShowButton(Rect r)を定義してみる
以下のようなEditorWindowクラスを作成してウィンドウを開いてみます。
using UnityEngine;
using UnityEditor;
public class TestEditorWindow : EditorWindow
{
[MenuItem("Tools/TestEditorWindow")]
static public void Open()
{
GetWindow<TestEditorWindow>();
}
void ShowButton(Rect r)
{
Debug.Log("called ShowButton");
}
}
ShowButtonメソッドが呼ばれていることが確認できました。(完
まとめ
EditorWindowクラスにShowButtonメソッドを作ると、Unity側から勝手に呼ばれてしまうのでShowButtonメソッドは作ってはいけません