当任何Button组件缺少方法时,有没有办法获得某种信息或警告?
我的意思是,当你为Button实现一个方法时,在场景中分配该方法然后,例如重命名该方法,重命名将不会更新场景中的方法调用,因此它显示“< Missing ScriptName.OldMethodName>”.
当发生这种情况时,我希望得到通知 – 至少在按下播放时,或者至少在部署应用程序时.
解决方法:
斯科特的answer非常接近你正在做的事情,并得出了这个答案.虽然缺少这么多东西.您需要做更多工作才能使该脚本正常工作.
1.您需要使用Resources.FindobjectsOfTypeAll获取场景中的所有按钮(包括非活动/禁用的按钮).
2.浏览按钮,检查保存该功能的类/脚本是否存在反射.你这样做是因为有时我们重命名脚本.这可能会导致问题.显示脚本的消息不存在.
你可以通过简单地检查Type.GetType(className);一片空白.
如果它为null,则不要同时进行下面的测试,因为包含Button的onClick函数的组件已被重命名.显示一条错误消息,指出此脚本已被删除或重命名.
3.如果该类存在,现在检查该函数是否存在于该按钮的onClick事件中注册的类中的反射.
这可以通过简单地检查type.getmethod(functionName);一片空白.
如果函数存在,那么Button就可以了.如果函数存在,则不必显示消息.停在这里.
如果返回null,则继续#4.
4.检查函数是否存在,但这一次,检查函数是否使用私有访问修饰符声明.
这是人们犯的典型错误.他们将功能声明为公共,通过编辑器分配,然后错误地将其从公共更改为私有.这应该可以工作,但将来会引起问题.
这可以通过简单地检查type.getmethod(functionName,BindingFlags.Instance | BindingFlags.NonPublic)来完成;一片空白.
如果该函数存在,则显示一条消息,警告您此函数的访问修饰符已从公共更改为私有,应更改回公共.
如果该功能不存在,请显示一条消息,警告您此功能不再存在或已重新命名.
下面是一个执行上面提到的所有内容的脚本.将它附加到一个空的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;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。