スコットのanswerは、あなたがやっていることに非常に近いエラーを発射し、この答えにつながったことができます。それは非常に多くのものが欠けていますが。このスクリプトを動作させるには、もっと多くの作業が必要です。
Resources.FindObjectsOfTypeAll
でシーン内のすべてのボタン(非アクティブ/無効のボタンを含む)を取得する必要があります。
ボタンを押して、その機能を保持するクラス/スクリプトがリフレクションで存在するかどうかを確認します。これは、スクリプトの名前を変更することがあるためです。これは問題を引き起こす可能性があります。スクリプトのShowメッセージが存在しません。
これは、Type.GetType(className);
がnull
であるかどうかを単に確認することで可能です。
の場合は、Button
のonClick
の機能を保持するコンポーネントの名前が変更されているため、以下の両方のテストも行わないでください。このスクリプトが削除または再命名されたことを示すエラーメッセージを表示します。クラス.IF
機能はボタンのonClick
イベントに登録されていることclass
に反射して存在するかどうかを確認今、存在しています。
これは、type.GetMethod(functionName);
がnull
であるかどうかを単にチェックすることによって行うことができます。
この関数が存在する場合、そのボタンは正常です。関数が存在する場合、メッセージを表示する必要はありません。ここで止まって。
null
を返す場合は、#4に進みます。
.Check機能の場合は存在しますが、機能がprivate
アクセス修飾子で宣言されている場合、この時間は、確認してください。
これは一般的な間違いです。彼らはpublic
として機能を宣言し、それをエディタで割り当ててから間違ってpublic
からprivate
に変更します。これはうまくいくはずですが、将来問題を引き起こす可能性があります。
これは、type.GetMethod(functionName, BindingFlags.Instance | BindingFlags.NonPublic);
がnull
であるかどうかを単にチェックすることによって行うことができます。
関数が存在する場合
は、この関数のアクセス修飾子が
private
へ
public
から変更されたと
public
に戻すべきであることを警告するメッセージが表示されます。
この機能が存在しない場合は、この機能が存在しないか、または名前が変更されたことを警告するメッセージを表示します。
以下は、上記のすべてを実行するスクリプトです。それを空のGameObjectに貼り付け、エディタでゲームを実行するときはいつでもその仕事をします。
using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
public class MissingOnClickDetector : MonoBehaviour
{
void Awake()
{
//Debug.Log("Class exist? " + classExist("ok.ButtonCallBackTest"));
searchForMissingOnClickFunctions();
}
void searchForMissingOnClickFunctions()
{
//Find all Buttons in the scene including hiding ones
Button[] allButtonScriptsInScene = Resources.FindObjectsOfTypeAll<Button>() as Button[];
for (int i = 0; i < allButtonScriptsInScene.Length; i++)
{
detectButtonError(allButtonScriptsInScene[i]);
}
}
//Searches each registered onClick function in each class
void detectButtonError(Button button)
{
for (int i = 0; i < button.onClick.GetPersistentEventCount(); i++)
{
//Get the target class name
UnityEngine.Object objectName = button.onClick.GetPersistentTarget(i);
//Get the function name
string methodName = button.onClick.GetPersistentMethodName(i); ;
//////////////////////////////////////////////////////CHECK CLASS/SCRIPT EXISTANCE/////////////////////////////////////////
//Check if the class that holds the function is null then exit if it is
if (objectName == null)
{
Debug.Log("<color=blue>Button \"" + button.gameObject.name +
"\" is missing the script that has the supposed button callback function. " +
"Please check if this script still exist or has been renamed</color>", button.gameObject);
continue; //Don't run code below
}
//Get full target class name(including namespace)
string objectFullNameWithNamespace = objectName.GetType().FullName;
//Check if the class that holds the function exist then exit if it does not
if (!classExist(objectFullNameWithNamespace))
{
Debug.Log("<color=blue>Button \"" + button.gameObject.name +
"\" is missing the script that has the supposed button callback function. " +
"Please check if this script still exist or has been renamed</color>", button.gameObject);
continue; //Don't run code below
}
//////////////////////////////////////////////////////CHECK FUNCTION EXISTANCE/////////////////////////////////////////
//Check if function Exist as public (the registered onClick function is ok if this returns true)
if (functionExistAsPublicInTarget(objectName, methodName))
{
//No Need to Log if function exist
//Debug.Log("<color=green>Function Exist</color>");
}
//Check if function Exist as private
else if (functionExistAsPrivateInTarget(objectName, methodName))
{
Debug.Log("<color=yellow>The registered Function \"" + methodName + "\" Exist as a private function. Please change \"" + methodName +
"\" function from the \"" + objectFullNameWithNamespace + "\" script to a public Access Modifier</color>", button.gameObject);
}
//Function does not even exist at-all
else
{
Debug.Log("<color=red>The \"" + methodName + "\" function Does NOT Exist in the \"" + objectFullNameWithNamespace + "\" script</color>", button.gameObject);
}
}
}
//Checks if class exit or has been renamed
bool classExist(string className)
{
Type myType = Type.GetType(className);
return myType != null;
}
//Checks if functions exist as public function
bool functionExistAsPublicInTarget(UnityEngine.Object target, string functionName)
{
Type type = target.GetType();
MethodInfo targetinfo = type.GetMethod(functionName);
return targetinfo != null;
}
//Checks if functions exist as private function
bool functionExistAsPrivateInTarget(UnityEngine.Object target, string functionName)
{
Type type = target.GetType();
MethodInfo targetinfo = type.GetMethod(functionName, BindingFlags.Instance | BindingFlags.NonPublic);
return targetinfo != null;
}
}
これは、デザイナーではなくコードで 'onClick'イベントを設定することで回避できます。 – Smartis