知识
反射
准备
- UnityEven是一个类,继承UnityEventBase
- UnityEventBase有一个私有字段m_Calls,该字段是一个类InvokableCallList,用于记录注册的方法,
- InvokableCallList有一个公有属性Count,该属性返回运行时注册的方法数量
使用反射
- 使用typeof获取UnityEventBase的类型
- 使用Type的GetField方法获取实例的成员,参数一 成员名,参数二搜素该成员的条件,不是公共成员且对象需实例化
- InvokableCallList只能在同一个程序集中使用,该类和UnityEventBase属于同一个程序集,使用程序集的GetType方法获取 InvokableCallList的类型
- 使用Type的GetProperty方法获取实例的属性
- 使用字段的GetValue和属性的GetVlaue方法获取Count的值
示例
using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;
public class GetUnityEventMethodCount : MonoBehaviour
{
public UnityEvent OnClick = new UnityEvent();
Type typeEventBase;
FieldInfo calls;
PropertyInfo methodCount;
Type typeInvokableCallList;
private void Awake()
{
typeEventBase = typeof(UnityEventBase);
calls = typeEventBase.GetField("m_Calls", BindingFlags.NonPublic | BindingFlags.Instance);
typeInvokableCallList = typeEventBase.Assembly.GetType("UnityEngine.Events.InvokableCallList");
methodCount = typeInvokableCallList.GetProperty("Count");
}
public int MethodCount()
{
return (int)methodCount.GetValue(calls.GetValue(OnClick));
}
private void OnGUI()
{
GUILayout.Label("事件注册的方法数量:" + MethodCount());
if (GUILayout.Button("运行时注册方法"))
{
OnClick.AddListener(TestMethod);
}
if (GUILayout.Button("运行时移除方法"))
{
OnClick.RemoveListener(TestMethod);
}
}
void TestMethod()
{
}
}