此功能能是基于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);
}