Skip to content

Instantly share code, notes, and snippets.

@AaronV
Created September 11, 2018 16:49
Show Gist options
  • Save AaronV/3fd7cc22039cf34f536ab98db47d044a to your computer and use it in GitHub Desktop.
Save AaronV/3fd7cc22039cf34f536ab98db47d044a to your computer and use it in GitHub Desktop.
Detect missing methods in scene UnityEvents.
/*
* Based on code found here: https://stackoverflow.com/questions/42784338/unity-missing-warning-when-button-has-missing-onclick/42788400?noredirect=1#comment91506017_42788400
*/
#if UNITY_EDITOR
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)
{
try
{
Type type = target.GetType();
MethodInfo targetinfo = type.GetMethod(functionName);
return targetinfo != null;
}
catch (AmbiguousMatchException)
{
return true;
}
}
//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;
}
}
#endif
@AaronV
Copy link
Author

AaronV commented Sep 11, 2018

See this Stack Overflow page for more context about this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment