我们用ILSpy反编译UnityEditor.dll,假设现在我们想要调用UnityEditor.EditorGUIUtility的这个DrawHorizontalSplitter方法,因为它是internal的,科普:
internal(内部)关键字是类型和类型的成员访问修饰符。只有在同一程序集中可访问,可以跨类。
注:ILspy是一个开源的.net反编译软件,使用十分方便,下载地址:https://github.com/icsharpcode/ILSpy/releases
所以我们就无法在外部直接调用DrawHorizontalSplitter这个方法。
但是,我们可以用反射的方式来调用。
我们封装一个反射工具的类:
using UnityEngine;
using System;
using System.Reflection;
public class ReflectionTools
{
public static void Call(string typeName, string methodName, params object[] args)
{
Call
这样,我们就可以调用了:
ReflectionTools.Call("UnityEditor.EditorGUIUtility, UnityEditor", "DrawHorizontalSplitter", new Rect(0f,0f,100f,100f));
同理,假设我们想用EditorStyles的toolbarSearchField属性:
我们先封装工具接口
using UnityEngine;
using System;
using System.Reflection;
public class ReflectionTools
{
public static T GetProperty(string typeName, string propertyName)
{
return GetProperty(null, typeName, propertyName);
}
public static T GetProperty(object instance, string typeName, string propertyName)
{
bool isStatic = null == instance;
Type type = Type.GetType(typeName);
T defaultValue = default(T);
if(null == type) return defaultValue;
BindingFlags flag = (isStatic ? BindingFlags.Static : BindingFlags.Instance);
PropertyInfo property = type.GetProperty(propertyName, flag | BindingFlags.Public | BindingFlags.NonPublic);
if(null == property)
{
Debug.LogError(string.Format("property {0} does not exist!",propertyName));
return defaultValue;
}
object result = property.GetValue(instance, null);
if(null == result)
return defaultValue;
if(!(result is T))
{
Debug.LogError(string.Format("property {0} cast failed!",propertyName));
return defaultValue;
}
return (T)result;
}
}
调用:
GUIStyle style = ReflectionTools.GetProperty("UnityEditor.EditorStyles, UnityEditor", "toolbarSearchField");
如果要获取成员变量,可以封装一个GetField方法,原理和GetProperty类似,只需要把type.GetProperty缓存type.GetField即可:
using UnityEngine;
using System;
using System.Reflection;
public class ReflectionTools
{
public static T GetField(string typeName, string fieldName)
{
return GetField(null, typeName, fieldName);
}
public static T GetField(object instance, string typeName, string fieldName)
{
bool isStatic = null == instance;
Type type = Type.GetType(typeName);
T defaultValue = default(T);
if(null == type) return defaultValue;
BindingFlags flag = (isStatic ? BindingFlags.Static : BindingFlags.Instance);
FieldInfo field = type.GetField(fieldName, flag | BindingFlags.Public | BindingFlags.NonPublic);
if(null == field)
{
Debug.LogError(string.Format("field {0} does not exist!",fieldName));
return defaultValue;
}
object result = field.GetValue(instance, null);
if(null == result)
return defaultValue;
if(!(result is T))
{
Debug.LogError(string.Format("field {0} cast failed!",fieldName));
return defaultValue;
}
return (T)result;
}
}