【Unity编辑器扩展】编辑器代码一键添加按钮响应事件

此功能能是基于UI变量代码生成工具的改良扩展:【Unity编辑器扩展】UI变量代码自动生成工具(编辑器扩展干货/大幅提高效率)_ui代码自动生成_TopGames的博客-CSDN博客

工具效果预览:

 UGUI的Button按钮在编辑面板添加响应事件非常繁琐,需要拖个节点,然后设置指定脚本类的方法,如下图:

 工具功能和使用方法:

1. 打开UI界面预制体;

2. 选择Button节点(支持多选),右键菜单->UIForm Fields Tool-> Add Button Event添加事件,并自动按钮节点名为Button的标识ID;

代码实现:

Button组件的onClick事件其实分了两种,Persistent和NonPersistent,Persistent是持久保存的,也就是在编辑器界面添加的。NonPersistent是代码运行时添加的。两种事件存在两个独立的事件列表,两者独立存在。

 为代码添加Persistent事件,需要用到UnityEditor.Events.UnityEventTools:

UnityEventTools.RemovePersistentListener:移除持久化按钮事件

UnityEditor.Events.UnityEventTools.AddPersistentListener: 添加持久化按钮事件

并且支持添加带有各种类型参数的按钮事件:

1. UnityEditor.Events.UnityEventTools.AddBoolPersistentListener

2. UnityEditor.Events.UnityEventTools.AddFloatPersistentListener

3. UnityEditor.Events.UnityEventTools.AddIntPersistentListener

4. UnityEditor.Events.UnityEventTools.AddObjectPersistentListener

5. UnityEditor.Events.UnityEventTools.AddStringPersistentListener

以添加带有字符串参数的按钮事件为例:

 1. 参数UnityEventBase unityEvent; 指的是按钮存储事件的变量。变量名为m_OnClick,这个变量是私有的,需要通过反射拿到:

var buttonCom = item.GetComponent<Button>();
var m_OnClick = buttonCom.GetType().GetField("m_OnClick", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(buttonCom) as UnityEvent;

2. 参数UnityAction<string> call,即按钮回调事件。这个事件是绑定的脚本类中的方法,因此创建时需指定Target和Method:

var btnEvent = UnityEngine.Events.UnityAction.CreateDelegate(typeof(UnityAction<string>), uiFormLogic, "YourButtonCallbackFunctionName") as UnityAction<string>;

为了避免重复添加事件,添加事件前可以清空当前持久化存储事件:

for (int i = m_OnClick.GetPersistentEventCount() - 1; i >= 0; i--)
                {
                    UnityEventTools.RemovePersistentListener(m_OnClick, i);
                }

完整代码:

[MenuItem("GameObject/UIForm Fields Tool/Add Button OnClick Event", false, priority = 1101)]
        private static void AddClickButtonEvent()
        {
            if (Selection.count <= 0) return;

            var uiForm = GetPrefabRootComponent<UIFormBase>();
            if (uiForm == null)
            {
                Debug.LogWarning("UIForm Script is not exist.");
                return;
            }
            bool hasChanged = false;
            foreach (var item in Selection.gameObjects)
            {
                var buttonCom = item?.GetComponent<Button>();
                
                if (buttonCom == null) continue;

                var m_OnClick = buttonCom.GetType().GetField("m_OnClick", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(buttonCom) as UnityEvent;
                var btnEvent = UnityEngine.Events.UnityAction.CreateDelegate(typeof(UnityAction<string>), uiForm, KEY_BUTTON_ONCLICK) as UnityAction<string>;
                for (int i = m_OnClick.GetPersistentEventCount() - 1; i >= 0; i--)
                {
                    UnityEventTools.RemovePersistentListener(m_OnClick, i);
                }
                UnityEditor.Events.UnityEventTools.AddStringPersistentListener(m_OnClick, btnEvent, buttonCom.name);
                hasChanged = true;
            }
            if (hasChanged) EditorUtility.SetDirty(uiForm);
        }

猜你喜欢

转载自blog.csdn.net/final5788/article/details/131719216