[Unity editor extension] editor code one-click add button response event

This function can be an improved extension based on the UI variable code generation tool: [Unity editor extension] UI variable code automatic generation tool (editor extension dry goods / greatly improve efficiency)_ui code automatic generation_TopGames' Blog-CSDN Blog

Tool effect preview:

 The Button button of UGUI is very cumbersome to add response events in the editing panel. It is necessary to drag a node and then set the method of specifying the script class, as shown in the following figure:

 Tool function and usage method:

1. Open the UI interface prefab;

2. Select the Button node (multiple selection is supported), right-click menu->UIForm Fields Tool->Add Button Event to add an event, and the button node is automatically named as the ID of Button;

Code:

The onClick event of the Button component is actually divided into two types, Persistent and NonPersistent. Persistent is persistent, which is added in the editor interface. NonPersistent is added when the code is running. There are two independent event lists for the two kinds of events, and the two exist independently.

 To add Persistent events to the code, you need to use UnityEditor.Events.UnityEventTools:

UnityEventTools.RemovePersistentListener: Remove persistent button events

UnityEditor.Events.UnityEventTools.AddPersistentListener: Add persistent button events

And it supports adding button events with various types of parameters:

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

Take for example adding a button event with a string parameter:

 1. The parameter UnityEventBase unityEvent; refers to the variable that stores the event of the button. The variable name is m_OnClick. This variable is private and needs to be obtained through reflection:

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. The parameter UnityAction<string> call, which is the button callback event. This event is a method in the bound script class, so you need to specify the Target and Method when creating it:

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

In order to avoid repeatedly adding events, you can clear the current persistent storage events before adding events:

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

Full code:

[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);
        }

Guess you like

Origin blog.csdn.net/final5788/article/details/131719216