MeowmentDebugTool/Packages/com.bywaystudios.meowmentdebugtool/Runtime/CustomButtonsModule.cs
2025-12-22 15:29:55 +08:00

181 lines
5.8 KiB
C#

using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace MeowmentDebugTool
{
/// <summary>
/// 自定义按钮模块 - 通过反射加载标记为DebugButton的方法
/// </summary>
public class CustomButtonsModule : IDebugModule
{
#region
private GameObject customButtonsPage;
private RectTransform buttonContainer;
private GameObject buttonPrefab;
private ScrollRect buttonsScrollRect;
// 自定义按钮回调
private Action<Button, TMP_Text> customButtonCallback;
// 保存的SDF字体资源
private TMP_FontAsset savedFontAsset = null;
// 关闭窗口回调
private Action onCloseWindowCallback;
#endregion
#region
public CustomButtonsModule(GameObject page, RectTransform container, GameObject prefab,
ScrollRect scrollRect, Action closeWindowCallback)
{
customButtonsPage = page;
buttonContainer = container;
buttonPrefab = prefab;
buttonsScrollRect = scrollRect;
onCloseWindowCallback = closeWindowCallback;
}
#endregion
#region IDebugModule
public void Initialize()
{
Debug.Log("[CustomButtonsModule] 初始化自定义按钮模块...");
LoadCustomButtons();
}
public GameObject GetPage()
{
return customButtonsPage;
}
public string GetModuleName()
{
return "自定义按钮";
}
#endregion
#region
/// <summary>
/// 设置SDF字体
/// </summary>
public void SetSDFFont(TMP_FontAsset fontAsset)
{
savedFontAsset = fontAsset;
}
/// <summary>
/// 设置自定义按钮回调
/// </summary>
public void SetCustomButtonCallback(Action<Button, TMP_Text> callback)
{
customButtonCallback = callback;
}
/// <summary>
/// 重新加载自定义按钮
/// </summary>
public void ReloadCustomButtons()
{
LoadCustomButtons();
}
#endregion
#region
/// <summary>
/// 加载所有自定义按钮(使用反射)
/// </summary>
private void LoadCustomButtons()
{
if (buttonContainer == null || buttonPrefab == null)
{
Debug.LogWarning("[CustomButtonsModule] 按钮容器或按钮预制件未设置");
return;
}
// 清空现有按钮
foreach (Transform child in buttonContainer)
{
UnityEngine.Object.Destroy(child.gameObject);
}
// 查找所有标记为DebugButton的方法
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
try
{
var types = assembly.GetTypes();
foreach (var type in types)
{
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var method in methods)
{
var attribute = method.GetCustomAttribute<DebugButtonAttribute>();
if (attribute != null)
{
CreateCustomButton(method, attribute);
}
}
}
}
catch (Exception e)
{
// 某些程序集可能无法访问,跳过
Debug.LogWarning($"[CustomButtonsModule] 无法访问程序集 {assembly.FullName}: {e.Message}");
}
}
}
private void CreateCustomButton(MethodInfo method, DebugButtonAttribute attribute)
{
GameObject buttonObj = UnityEngine.Object.Instantiate(buttonPrefab, buttonContainer);
Button button = buttonObj.GetComponent<Button>();
TMP_Text buttonText = buttonObj.GetComponentInChildren<TMP_Text>();
Image buttonImage = buttonObj.GetComponent<Image>();
// 设置按钮文本
if (buttonText != null)
{
buttonText.text = string.IsNullOrEmpty(attribute.DisplayName) ? method.Name : attribute.DisplayName;
// 应用保存的字体
if (savedFontAsset != null)
{
buttonText.font = savedFontAsset;
}
}
// 设置按钮颜色
if (buttonImage != null && attribute.ButtonColor != default(Color))
{
buttonImage.color = attribute.ButtonColor;
}
// 设置按钮点击事件
button.onClick.AddListener(() =>
{
try
{
method.Invoke(null, null);
Debug.Log($"[CustomButtonsModule] 执行调试方法: {method.Name}");
// 调用回调
customButtonCallback?.Invoke(button, buttonText);
customButtonCallback = null;
// 点击按钮后关闭主窗口
onCloseWindowCallback?.Invoke();
}
catch (Exception e)
{
Debug.LogError($"[CustomButtonsModule] 执行调试方法 {method.Name} 时出错: {e.Message}");
}
});
}
#endregion
}
}