Unity Inspector中如何选择EventsManager的函数作为下拉选项?
解决Unity中BtnController Inspector显示EventsManager函数下拉的问题
你原来使用的Func<EventsManager>完全不符合需求:这是一个返回EventsManager实例的委托类型,和你要调用EventsManager无参方法的目标不匹配,而且Unity Inspector默认不支持显示这种非序列化的委托,所以看不到函数列表。下面提供三种可行的解决方案:
方案1:用UnityEvent(原生支持,操作简单)
UnityEvent是Unity自带的可序列化事件系统,能直接在Inspector里绑定目标对象和方法。因为EventsManager是单例,你可以自动获取实例,也允许手动绑定:
using UnityEngine; using UnityEngine.Events; public class BtnController : MonoBehaviour { private AssetBundle assetBundle; // 定义可在Inspector编辑的UnityEvent public UnityEvent onButtonClick; // 按钮点击时触发的方法(绑定给Button组件的OnClick事件) public void OnButtonClicked() { onButtonClick?.Invoke(); } }
Inspector操作步骤:
- 选中带BtnController的按钮对象,找到组件里的
onButtonClick事件 - 点击"+"号,拖拽场景中的EventsManager实例到对象槽(因为它是MonoBehaviour,必须存在于场景中)
- 在下拉菜单里选择EventsManager的公开方法:
StartExperience/PauseExperience/ResumeExperience
方案2:枚举+反射(直接下拉选方法,无需拖拽)
通过枚举对应EventsManager的所有目标方法,点击按钮时用反射调用对应函数,实现Inspector下拉选择:
using UnityEngine; using System.Reflection; public class BtnController : MonoBehaviour { private AssetBundle assetBundle; // 枚举对应EventsManager的所有公开方法 public enum EventMethod { StartExperience, PauseExperience, ResumeExperience } [Tooltip("选择要触发的EventsManager方法")] public EventMethod selectedMethod; // 按钮点击触发 public void OnButtonClicked() { if (EventsManager.current == null) { Debug.LogError("EventsManager实例不存在!"); return; } // 通过反射调用选中的方法 MethodInfo targetMethod = typeof(EventsManager).GetMethod( selectedMethod.ToString(), BindingFlags.Public | BindingFlags.Instance ); targetMethod?.Invoke(EventsManager.current, null); } }
这样在Inspector里就能看到一个下拉菜单,直接选择要触发的方法即可。
方案3:自定义可序列化委托(限制可选方法范围)
如果想要更精准地限制只能选择EventsManager的无参公开方法,可以自定义可序列化委托和编辑器抽屉:
1. 定义可序列化委托(放在普通脚本文件夹)
using UnityEngine; using System; [Serializable] public class EventsManagerMethod : UnityEvent { }
2. 自定义PropertyDrawer(放在Editor文件夹)
using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(EventsManagerMethod))] public class EventsManagerMethodDrawer : UnityEventDrawer { protected override bool IsValidTarget(Object target) { // 只允许选择EventsManager类型的对象 return target is EventsManager; } protected override bool IsValidMethod(UnityEditorInternal.MonoScript script, string methodName, System.Type[] parameterTypes) { // 只允许选择无参数的公开实例方法 if (parameterTypes.Length != 0) return false; var method = script.GetClass().GetMethod(methodName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); return method != null && method.GetParameters().Length == 0; } }
3. 在BtnController中使用
using UnityEngine; public class BtnController : MonoBehaviour { private AssetBundle assetBundle; public EventsManagerMethod onButtonClick; public void OnButtonClicked() { onButtonClick?.Invoke(); } }
此时Inspector里的onButtonClick事件只能选择EventsManager的无参公开方法,完全贴合你的需求。
内容的提问来源于stack exchange,提问作者Ando
相关产品推荐
相关产品推荐

