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

1181 lines
58 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;
namespace MeowmentDebugTool
{
/// <summary>
/// 运行时UI生成器 - 自动创建调试工具的完整UI
/// </summary>
public static class RuntimeUIGenerator
{
private const int CANVAS_WIDTH = 1080;
private const int CANVAS_HEIGHT = 2340;
/// <summary>
/// 创建完整的调试工具UI
/// </summary>
public static UniversalDebugTool CreateDebugToolUI()
{
// 检查并创建EventSystem
EnsureEventSystem();
// 创建根Canvas
GameObject canvasObj = new GameObject("UniversalDebugTool_Canvas");
Canvas canvas = canvasObj.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = 30000;
canvas.overrideSorting = true;
CanvasScaler scaler = canvasObj.AddComponent<CanvasScaler>();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(CANVAS_WIDTH, CANVAS_HEIGHT);
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
scaler.matchWidthOrHeight = 0.5f;
canvasObj.AddComponent<GraphicRaycaster>();
// 创建 UniversalDebugTool 组件
UniversalDebugTool tool = canvasObj.AddComponent<UniversalDebugTool>();
// 创建主窗口
GameObject mainWindow = CreateMainWindow(canvasObj.transform);
// 创建悬浮按钮
GameObject floatingButton = CreateFloatingButton(canvasObj.transform);
// 创建标签页
GameObject tabContainer = mainWindow.transform.Find("TabButtonContainer").gameObject;
GameObject contentContainer = mainWindow.transform.Find("ContentContainer").gameObject;
GameObject parametersPage = CreateParametersPage(contentContainer.transform);
GameObject customButtonsPage = CreateCustomButtonsPage(contentContainer.transform);
GameObject toolbarPage = CreateToolbarPage(contentContainer.transform);
GameObject settingsPage = CreateSettingsPage(contentContainer.transform);
GameObject consolePage = CreateConsolePage(contentContainer.transform);
// 创建输入对话框
GameObject inputDialog = CreateInputDialog(canvasObj.transform);
// 设置引用
SetupReferences(tool, canvas, mainWindow, floatingButton,
parametersPage, customButtonsPage, toolbarPage, settingsPage, consolePage, inputDialog);
return tool;
}
private static GameObject CreateMainWindow(Transform parent)
{
GameObject mainWindow = new GameObject("MainWindow");
mainWindow.transform.SetParent(parent, false);
RectTransform rect = mainWindow.AddComponent<RectTransform>();
rect.anchorMin = new Vector2(0, 1);
rect.anchorMax = new Vector2(0, 1);
rect.pivot = new Vector2(0, 1);
rect.sizeDelta = new Vector2(CANVAS_WIDTH, CANVAS_HEIGHT);
rect.anchoredPosition = Vector2.zero;
// 背景
Image bg = mainWindow.AddComponent<Image>();
bg.color = new Color(0.1f, 0.1f, 0.1f, 0.95f);
// 关闭按钮(左上角)
GameObject closeBtn = CreateButton("CloseButton", mainWindow.transform, "X");
RectTransform closeBtnRect = closeBtn.GetComponent<RectTransform>();
closeBtnRect.anchorMin = new Vector2(0, 1);
closeBtnRect.anchorMax = new Vector2(0, 1);
closeBtnRect.pivot = new Vector2(0, 1);
closeBtnRect.sizeDelta = new Vector2(100, 100);
closeBtnRect.anchoredPosition = new Vector2(10, -10);
closeBtn.GetComponent<Image>().color = new Color(0.8f, 0.2f, 0.2f, 1f);
// 标签按钮容器(从关闭按钮右侧开始)
GameObject tabContainer = new GameObject("TabButtonContainer");
tabContainer.transform.SetParent(mainWindow.transform, false);
RectTransform tabRect = tabContainer.AddComponent<RectTransform>();
tabRect.anchorMin = new Vector2(0, 1);
tabRect.anchorMax = new Vector2(1, 1);
tabRect.pivot = new Vector2(0, 1);
tabRect.sizeDelta = new Vector2(-120, 100);
tabRect.anchoredPosition = new Vector2(120, 0);
HorizontalLayoutGroup tabLayout = tabContainer.AddComponent<HorizontalLayoutGroup>();
tabLayout.childControlWidth = true;
tabLayout.childControlHeight = true;
tabLayout.childForceExpandWidth = true;
tabLayout.childForceExpandHeight = true;
tabLayout.spacing = 10;
tabLayout.padding = new RectOffset(10, 20, 10, 10);
// 内容容器
GameObject contentContainer = new GameObject("ContentContainer");
contentContainer.transform.SetParent(mainWindow.transform, false);
RectTransform contentRect = contentContainer.AddComponent<RectTransform>();
contentRect.anchorMin = new Vector2(0, 0);
contentRect.anchorMax = new Vector2(1, 1);
contentRect.pivot = new Vector2(0.5f, 0.5f);
contentRect.offsetMin = new Vector2(20, 20);
contentRect.offsetMax = new Vector2(-20, -120);
return mainWindow;
}
private static GameObject CreateFloatingButton(Transform parent)
{
GameObject floatBtn = new GameObject("FloatingButton");
floatBtn.transform.SetParent(parent, false);
RectTransform rect = floatBtn.AddComponent<RectTransform>();
rect.anchorMin = new Vector2(0.5f, 0.5f);
rect.anchorMax = new Vector2(0.5f, 0.5f);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.sizeDelta = new Vector2(120, 120);
rect.anchoredPosition = new Vector2(400, 0);
Image img = floatBtn.AddComponent<Image>();
img.color = new Color(0.2f, 0.6f, 1f, 0.8f);
Button btn = floatBtn.AddComponent<Button>();
// 添加文本
GameObject textObj = new GameObject("Text");
textObj.transform.SetParent(floatBtn.transform, false);
RectTransform textRect = textObj.AddComponent<RectTransform>();
textRect.anchorMin = Vector2.zero;
textRect.anchorMax = Vector2.one;
textRect.sizeDelta = Vector2.zero;
TextMeshProUGUI text = textObj.AddComponent<TextMeshProUGUI>();
text.text = "调试";
text.fontSize = 36;
text.alignment = TextAlignmentOptions.Center;
text.color = Color.white;
// 添加拖拽组件
DraggableFloatingButton draggable = floatBtn.AddComponent<DraggableFloatingButton>();
draggable.clampToScreen = true;
draggable.snapToEdge = true;
return floatBtn;
}
private static GameObject CreateParametersPage(Transform parent)
{
GameObject page = new GameObject("ParametersPage");
page.transform.SetParent(parent, false);
RectTransform rect = page.AddComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero;
ScrollRect scroll = page.AddComponent<ScrollRect>();
scroll.horizontal = false;
scroll.vertical = true;
GameObject viewport = new GameObject("Viewport");
viewport.transform.SetParent(page.transform, false);
RectTransform vpRect = viewport.AddComponent<RectTransform>();
vpRect.anchorMin = Vector2.zero;
vpRect.anchorMax = Vector2.one;
vpRect.sizeDelta = Vector2.zero;
viewport.AddComponent<Image>().color = new Color(0, 0, 0, 0.1f);
viewport.AddComponent<Mask>().showMaskGraphic = false;
GameObject content = new GameObject("Content");
content.transform.SetParent(viewport.transform, false);
RectTransform contentRect = content.AddComponent<RectTransform>();
contentRect.anchorMin = new Vector2(0, 1);
contentRect.anchorMax = new Vector2(1, 1);
contentRect.pivot = new Vector2(0.5f, 1);
contentRect.sizeDelta = new Vector2(0, 2000);
VerticalLayoutGroup layout = content.AddComponent<VerticalLayoutGroup>();
layout.childControlWidth = true;
layout.childControlHeight = true;
layout.childForceExpandWidth = true;
layout.childForceExpandHeight = false;
layout.spacing = 20;
layout.padding = new RectOffset(20, 20, 20, 20);
ContentSizeFitter fitter = content.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
scroll.viewport = vpRect;
scroll.content = contentRect;
// 设备信息文本
GameObject deviceInfo = CreateTextObject("DeviceInfo", content.transform, "设备信息");
// 系统信息文本
GameObject systemInfo = CreateTextObject("SystemInfo", content.transform, "系统信息");
return page;
}
private static GameObject CreateCustomButtonsPage(Transform parent)
{
GameObject page = new GameObject("CustomButtonsPage");
page.transform.SetParent(parent, false);
RectTransform rect = page.AddComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero;
ScrollRect scroll = page.AddComponent<ScrollRect>();
GameObject viewport = new GameObject("Viewport");
viewport.transform.SetParent(page.transform, false);
RectTransform vpRect = viewport.AddComponent<RectTransform>();
vpRect.anchorMin = Vector2.zero;
vpRect.anchorMax = Vector2.one;
vpRect.sizeDelta = Vector2.zero;
viewport.AddComponent<Mask>().showMaskGraphic = false;
GameObject buttonContainer = new GameObject("ButtonContainer");
buttonContainer.transform.SetParent(viewport.transform, false);
RectTransform containerRect = buttonContainer.AddComponent<RectTransform>();
containerRect.anchorMin = new Vector2(0, 1);
containerRect.anchorMax = new Vector2(1, 1);
containerRect.pivot = new Vector2(0.5f, 1);
GridLayoutGroup grid = buttonContainer.AddComponent<GridLayoutGroup>();
grid.cellSize = new Vector2(300, 100);
grid.spacing = new Vector2(20, 20);
grid.padding = new RectOffset(20, 20, 20, 20);
grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
grid.constraintCount = 3;
ContentSizeFitter fitter = buttonContainer.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
scroll.viewport = vpRect;
scroll.content = containerRect;
return page;
}
private static GameObject CreateToolbarPage(Transform parent)
{
GameObject page = new GameObject("ToolbarPage");
page.transform.SetParent(parent, false);
RectTransform rect = page.AddComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero;
// 时间调整面板
GameObject timePanel = new GameObject("TimeAdjustPanel");
timePanel.transform.SetParent(page.transform, false);
RectTransform timePanelRect = timePanel.AddComponent<RectTransform>();
timePanelRect.anchorMin = new Vector2(0, 0.7f);
timePanelRect.anchorMax = new Vector2(1, 1);
timePanelRect.offsetMin = new Vector2(20, 0);
timePanelRect.offsetMax = new Vector2(-20, -20);
VerticalLayoutGroup vLayout = timePanel.AddComponent<VerticalLayoutGroup>();
vLayout.spacing = 20;
vLayout.padding = new RectOffset(20, 20, 20, 20);
vLayout.childControlWidth = true;
vLayout.childControlHeight = false;
vLayout.childForceExpandWidth = true;
// 标题
GameObject title = CreateTextObject("Title", timePanel.transform, "时间调整");
title.GetComponent<TextMeshProUGUI>().fontSize = 36;
title.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
title.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 60);
// 滑块
GameObject slider = CreateSlider("TimeAdjustSlider", timePanel.transform);
slider.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 60);
// 数值显示
GameObject valueText = CreateTextObject("TimeAdjustValueText", timePanel.transform, "60 秒");
valueText.GetComponent<TextMeshProUGUI>().fontSize = 32;
valueText.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
valueText.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 50);
// 按钮容器
GameObject btnContainer = new GameObject("ButtonContainer");
btnContainer.transform.SetParent(timePanel.transform, false);
RectTransform btnRect = btnContainer.AddComponent<RectTransform>();
btnRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup hLayout = btnContainer.AddComponent<HorizontalLayoutGroup>();
hLayout.spacing = 20;
hLayout.childControlWidth = true;
hLayout.childControlHeight = true;
hLayout.childForceExpandWidth = true;
hLayout.childForceExpandHeight = true;
GameObject increaseBtn = CreateButton("TimeIncreaseButton", btnContainer.transform, "+10秒");
GameObject decreaseBtn = CreateButton("TimeDecreaseButton", btnContainer.transform, "-10秒");
// 暂时隐藏按钮
GameObject hideBtn = CreateButton("HideTemporarilyButton", timePanel.transform, "暂时隐藏 (5秒)");
hideBtn.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 100);
hideBtn.GetComponent<Image>().color = new Color(0.5f, 0.3f, 0.1f, 1f); // 橙褐色
hideBtn.GetComponent<Button>().onClick.AddListener(() => {
UniversalDebugTool.HideTemporarily(5f);
});
return page;
}
private static GameObject CreateSettingsPage(Transform parent)
{
GameObject page = new GameObject("SettingsPage");
page.transform.SetParent(parent, false);
RectTransform rect = page.AddComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero;
// 分辨率设置面板
GameObject resPanel = new GameObject("ResolutionPanel");
resPanel.transform.SetParent(page.transform, false);
RectTransform resPanelRect = resPanel.AddComponent<RectTransform>();
resPanelRect.anchorMin = new Vector2(0, 0.6f);
resPanelRect.anchorMax = new Vector2(1, 1);
resPanelRect.offsetMin = new Vector2(20, 0);
resPanelRect.offsetMax = new Vector2(-20, -20);
VerticalLayoutGroup vLayout = resPanel.AddComponent<VerticalLayoutGroup>();
vLayout.spacing = 30;
vLayout.padding = new RectOffset(40, 40, 40, 40);
vLayout.childControlWidth = true;
vLayout.childControlHeight = false;
vLayout.childForceExpandWidth = true;
// 标题
GameObject title = CreateTextObject("Title", resPanel.transform, "分辨率设置");
title.GetComponent<TextMeshProUGUI>().fontSize = 36;
title.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
title.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 60);
// 输入字段容器
GameObject inputContainer = new GameObject("InputContainer");
inputContainer.transform.SetParent(resPanel.transform, false);
RectTransform inputRect = inputContainer.AddComponent<RectTransform>();
inputRect.sizeDelta = new Vector2(0, 120);
HorizontalLayoutGroup hLayout = inputContainer.AddComponent<HorizontalLayoutGroup>();
hLayout.spacing = 20;
hLayout.childControlWidth = true;
hLayout.childControlHeight = true;
hLayout.childForceExpandWidth = true;
hLayout.childForceExpandHeight = true;
// 宽度输入
GameObject widthInput = CreateInputField("WidthInputField", inputContainer.transform, "1080");
widthInput.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 100);
// x 分隔符
GameObject separator = CreateTextObject("X", inputContainer.transform, "×");
separator.GetComponent<TextMeshProUGUI>().fontSize = 48;
separator.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
separator.GetComponent<RectTransform>().sizeDelta = new Vector2(80, 100);
// 高度输入
GameObject heightInput = CreateInputField("HeightInputField", inputContainer.transform, "2340");
heightInput.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 100);
// 按钮容器
GameObject btnContainer = new GameObject("ButtonContainer");
btnContainer.transform.SetParent(resPanel.transform, false);
RectTransform btnRect = btnContainer.AddComponent<RectTransform>();
btnRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup btnLayout = btnContainer.AddComponent<HorizontalLayoutGroup>();
btnLayout.spacing = 20;
btnLayout.childControlWidth = true;
btnLayout.childControlHeight = true;
btnLayout.childForceExpandWidth = true;
btnLayout.childForceExpandHeight = true;
GameObject applyBtn = CreateButton("ApplyResolutionButton", btnContainer.transform, "应用");
GameObject resetBtn = CreateButton("ResetResolutionButton", btnContainer.transform, "重置");
// 当前分辨率显示
GameObject currentText = CreateTextObject("CurrentResolutionText", resPanel.transform, "当前: 1080×2340");
currentText.GetComponent<TextMeshProUGUI>().fontSize = 28;
currentText.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
currentText.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 60);
return page;
}
private static GameObject CreateConsolePage(Transform parent)
{
GameObject page = new GameObject("ConsolePage");
page.transform.SetParent(parent, false);
RectTransform rect = page.AddComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero;
VerticalLayoutGroup vLayout = page.AddComponent<VerticalLayoutGroup>();
vLayout.spacing = 10;
vLayout.padding = new RectOffset(10, 10, 10, 10);
vLayout.childControlWidth = true;
vLayout.childControlHeight = false;
vLayout.childForceExpandWidth = true;
vLayout.childForceExpandHeight = false;
// 控制面板
GameObject controlPanel = new GameObject("ControlPanel");
controlPanel.transform.SetParent(page.transform, false);
RectTransform controlRect = controlPanel.AddComponent<RectTransform>();
controlRect.sizeDelta = new Vector2(0, 40);
// 添加LayoutElement来控制高度
LayoutElement controlLayout = controlPanel.AddComponent<LayoutElement>();
controlLayout.preferredHeight = 40;
controlLayout.flexibleHeight = 0;
HorizontalLayoutGroup hLayout = controlPanel.AddComponent<HorizontalLayoutGroup>();
hLayout.spacing = 10;
hLayout.padding = new RectOffset(10, 10, 10, 10);
hLayout.childControlWidth = false;
hLayout.childControlHeight = true;
hLayout.childForceExpandHeight = false;
// 清空按钮
GameObject clearBtn = CreateButton("ConsoleClearButton", controlPanel.transform, "清空");
clearBtn.GetComponent<RectTransform>().sizeDelta = new Vector2(150, 0);
LayoutElement clearLayout = clearBtn.AddComponent<LayoutElement>();
clearLayout.preferredHeight = 35;
// 锁定滚动Toggle
GameObject lockToggle = CreateToggle("ConsoleLockScrollToggle", controlPanel.transform, "锁定滚动");
lockToggle.GetComponent<RectTransform>().sizeDelta = new Vector2(180, 0);
LayoutElement lockLayout = lockToggle.AddComponent<LayoutElement>();
lockLayout.preferredHeight = 35;
// 过滤器Toggles
GameObject infoToggle = CreateToggle("ConsoleInfoFilterToggle", controlPanel.transform, "Info (0)");
infoToggle.GetComponent<RectTransform>().sizeDelta = new Vector2(150, 0);
infoToggle.GetComponent<Toggle>().isOn = true;
LayoutElement infoLayout = infoToggle.AddComponent<LayoutElement>();
infoLayout.preferredHeight = 35;
GameObject warningToggle = CreateToggle("ConsoleWarningFilterToggle", controlPanel.transform, "Warning (0)");
warningToggle.GetComponent<RectTransform>().sizeDelta = new Vector2(180, 0);
warningToggle.GetComponent<Toggle>().isOn = true;
LayoutElement warningLayout = warningToggle.AddComponent<LayoutElement>();
warningLayout.preferredHeight = 35;
GameObject errorToggle = CreateToggle("ConsoleErrorFilterToggle", controlPanel.transform, "Error (0)");
errorToggle.GetComponent<RectTransform>().sizeDelta = new Vector2(150, 0);
errorToggle.GetComponent<Toggle>().isOn = true;
LayoutElement errorLayout = errorToggle.AddComponent<LayoutElement>();
errorLayout.preferredHeight = 35;
GameObject fatalToggle = CreateToggle("ConsoleFatalFilterToggle", controlPanel.transform, "Fatal (0)");
fatalToggle.GetComponent<RectTransform>().sizeDelta = new Vector2(150, 0);
fatalToggle.GetComponent<Toggle>().isOn = true;
LayoutElement fatalLayout = fatalToggle.AddComponent<LayoutElement>();
fatalLayout.preferredHeight = 35;
// 日志区域 (60%)
GameObject logArea = new GameObject("LogArea");
logArea.transform.SetParent(page.transform, false);
RectTransform logAreaRect = logArea.AddComponent<RectTransform>();
logAreaRect.sizeDelta = new Vector2(0, 1300);
LayoutElement logAreaLayout = logArea.AddComponent<LayoutElement>();
logAreaLayout.preferredHeight = 1300;
logAreaLayout.flexibleHeight = 0;
// 日志ScrollView
GameObject logScrollView = new GameObject("ConsoleLogScrollView");
logScrollView.transform.SetParent(logArea.transform, false);
RectTransform logScrollRect = logScrollView.AddComponent<RectTransform>();
logScrollRect.anchorMin = Vector2.zero;
logScrollRect.anchorMax = Vector2.one;
logScrollRect.sizeDelta = Vector2.zero;
ScrollRect logScroll = logScrollView.AddComponent<ScrollRect>();
logScroll.horizontal = false;
logScroll.vertical = true;
logScroll.movementType = ScrollRect.MovementType.Elastic;
// Viewport
GameObject logViewport = new GameObject("Viewport");
logViewport.transform.SetParent(logScrollView.transform, false);
RectTransform logViewportRect = logViewport.AddComponent<RectTransform>();
logViewportRect.anchorMin = Vector2.zero;
logViewportRect.anchorMax = Vector2.one;
logViewportRect.sizeDelta = Vector2.zero;
logViewport.AddComponent<Image>().color = new Color(0.05f, 0.05f, 0.05f, 1f);
logViewport.AddComponent<Mask>().showMaskGraphic = true;
logScroll.viewport = logViewportRect;
// Content
GameObject logContent = new GameObject("ConsoleLogContent");
logContent.transform.SetParent(logViewport.transform, false);
RectTransform logContentRect = logContent.AddComponent<RectTransform>();
logContentRect.anchorMin = new Vector2(0, 1);
logContentRect.anchorMax = new Vector2(1, 1);
logContentRect.pivot = new Vector2(0.5f, 1);
logContentRect.sizeDelta = new Vector2(0, 0);
VerticalLayoutGroup logVLayout = logContent.AddComponent<VerticalLayoutGroup>();
logVLayout.spacing = 2;
logVLayout.childAlignment = TextAnchor.UpperCenter;
logVLayout.childControlWidth = true;
logVLayout.childControlHeight = true;
logVLayout.childForceExpandWidth = true;
logVLayout.childForceExpandHeight = false;
ContentSizeFitter logFitter = logContent.AddComponent<ContentSizeFitter>();
logFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
logScroll.content = logContentRect;
// 详情区域 (40%)
GameObject detailArea = new GameObject("DetailArea");
detailArea.transform.SetParent(page.transform, false);
RectTransform detailAreaRect = detailArea.AddComponent<RectTransform>();
detailAreaRect.sizeDelta = new Vector2(0, 800);
LayoutElement detailAreaLayout = detailArea.AddComponent<LayoutElement>();
detailAreaLayout.preferredHeight = 800;
detailAreaLayout.flexibleHeight = 0;
// 详情ScrollView
GameObject detailScrollView = new GameObject("ConsoleDetailScrollView");
detailScrollView.transform.SetParent(detailArea.transform, false);
RectTransform detailScrollRect = detailScrollView.AddComponent<RectTransform>();
detailScrollRect.anchorMin = Vector2.zero;
detailScrollRect.anchorMax = Vector2.one;
detailScrollRect.sizeDelta = Vector2.zero;
ScrollRect detailScroll = detailScrollView.AddComponent<ScrollRect>();
detailScroll.horizontal = false;
detailScroll.vertical = true;
detailScroll.movementType = ScrollRect.MovementType.Clamped;
// Viewport
GameObject detailViewport = new GameObject("Viewport");
detailViewport.transform.SetParent(detailScrollView.transform, false);
RectTransform detailViewportRect = detailViewport.AddComponent<RectTransform>();
detailViewportRect.anchorMin = Vector2.zero;
detailViewportRect.anchorMax = Vector2.one;
detailViewportRect.sizeDelta = Vector2.zero;
detailViewport.AddComponent<Image>().color = new Color(0.08f, 0.08f, 0.08f, 1f);
detailViewport.AddComponent<Mask>().showMaskGraphic = true;
detailScroll.viewport = detailViewportRect;
// Content
GameObject detailContent = new GameObject("Content");
detailContent.transform.SetParent(detailViewport.transform, false);
RectTransform detailContentRect = detailContent.AddComponent<RectTransform>();
detailContentRect.anchorMin = new Vector2(0, 1);
detailContentRect.anchorMax = new Vector2(1, 1);
detailContentRect.pivot = new Vector2(0.5f, 1);
detailContentRect.sizeDelta = new Vector2(-20, 0);
detailContentRect.anchoredPosition = Vector2.zero;
// 详情文本
GameObject detailText = CreateTextObject("ConsoleDetailText", detailContent.transform, "点击日志查看详细信息...");
TextMeshProUGUI detailTMP = detailText.GetComponent<TextMeshProUGUI>();
detailTMP.fontSize = 24;
detailTMP.alignment = TextAlignmentOptions.TopLeft;
detailTMP.enableWordWrapping = true;
detailTMP.overflowMode = TextOverflowModes.Overflow;
detailTMP.richText = true;
detailTMP.color = new Color(0.8f, 0.8f, 0.8f, 1f);
RectTransform detailTextRect = detailText.GetComponent<RectTransform>();
detailTextRect.anchorMin = new Vector2(0, 1);
detailTextRect.anchorMax = new Vector2(1, 1);
detailTextRect.pivot = new Vector2(0.5f, 1);
detailTextRect.sizeDelta = new Vector2(0, 0);
ContentSizeFitter detailFitter = detailText.AddComponent<ContentSizeFitter>();
detailFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
detailScroll.content = detailContentRect;
return page;
}
private static GameObject CreateInputDialog(Transform parent)
{
GameObject dialog = new GameObject("InputDialog");
dialog.transform.SetParent(parent, false);
RectTransform rect = dialog.AddComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.sizeDelta = Vector2.zero;
// 半透明背景
Image bg = dialog.AddComponent<Image>();
bg.color = new Color(0, 0, 0, 0.8f);
// 面板
GameObject panel = new GameObject("Panel");
panel.transform.SetParent(dialog.transform, false);
RectTransform panelRect = panel.AddComponent<RectTransform>();
panelRect.anchorMin = new Vector2(0.5f, 0.5f);
panelRect.anchorMax = new Vector2(0.5f, 0.5f);
panelRect.sizeDelta = new Vector2(900, 500);
panel.AddComponent<Image>().color = new Color(0.2f, 0.2f, 0.2f, 1f);
VerticalLayoutGroup vLayout = panel.AddComponent<VerticalLayoutGroup>();
vLayout.spacing = 30;
vLayout.padding = new RectOffset(40, 40, 40, 40);
vLayout.childControlWidth = true;
vLayout.childControlHeight = false;
vLayout.childForceExpandWidth = true;
// 标题
GameObject title = CreateTextObject("Title", panel.transform, "输入");
title.GetComponent<TextMeshProUGUI>().fontSize = 40;
title.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
title.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 70);
// 输入框
GameObject inputField = CreateInputField("InputField", panel.transform, "请输入...");
inputField.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 120);
// 按钮容器
GameObject btnContainer = new GameObject("ButtonContainer");
btnContainer.transform.SetParent(panel.transform, false);
RectTransform btnRect = btnContainer.AddComponent<RectTransform>();
btnRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup hLayout = btnContainer.AddComponent<HorizontalLayoutGroup>();
hLayout.spacing = 40;
hLayout.childControlWidth = true;
hLayout.childControlHeight = true;
hLayout.childForceExpandWidth = true;
hLayout.childForceExpandHeight = true;
GameObject confirmBtn = CreateButton("ConfirmButton", btnContainer.transform, "确定");
confirmBtn.GetComponent<Image>().color = new Color(0.2f, 0.6f, 0.2f, 1f);
GameObject cancelBtn = CreateButton("CancelButton", btnContainer.transform, "取消");
cancelBtn.GetComponent<Image>().color = new Color(0.6f, 0.2f, 0.2f, 1f);
dialog.SetActive(false);
return dialog;
}
#region Helper Methods
/// <summary>
/// 获取TMP默认字体如果没有则返回null
/// </summary>
private static TMP_FontAsset GetDefaultFont()
{
// 尝试获取TMP的默认字体
TMP_FontAsset defaultFont = TMP_Settings.defaultFontAsset;
// 如果没有默认字体尝试加载LiberationSans
if (defaultFont == null)
{
defaultFont = Resources.Load<TMP_FontAsset>("Fonts & Materials/LiberationSans SDF");
}
return defaultFont;
}
private static GameObject CreateButton(string name, Transform parent, string text)
{
GameObject btn = new GameObject(name);
btn.transform.SetParent(parent, false);
RectTransform rect = btn.AddComponent<RectTransform>();
rect.sizeDelta = new Vector2(200, 80);
Image img = btn.AddComponent<Image>();
img.color = new Color(0.3f, 0.3f, 0.3f, 1f);
Button button = btn.AddComponent<Button>();
GameObject textObj = new GameObject("Text");
textObj.transform.SetParent(btn.transform, false);
RectTransform textRect = textObj.AddComponent<RectTransform>();
textRect.anchorMin = Vector2.zero;
textRect.anchorMax = Vector2.one;
textRect.sizeDelta = Vector2.zero;
TextMeshProUGUI tmp = textObj.AddComponent<TextMeshProUGUI>();
tmp.text = text;
tmp.fontSize = 32;
tmp.alignment = TextAlignmentOptions.Center;
tmp.color = Color.white;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
tmp.font = defaultFont;
}
return btn;
}
private static GameObject CreateTextObject(string name, Transform parent, string text)
{
GameObject textObj = new GameObject(name);
textObj.transform.SetParent(parent, false);
RectTransform rect = textObj.AddComponent<RectTransform>();
rect.sizeDelta = new Vector2(800, 200);
TextMeshProUGUI tmp = textObj.AddComponent<TextMeshProUGUI>();
tmp.text = text;
tmp.fontSize = 28;
tmp.alignment = TextAlignmentOptions.TopLeft;
tmp.color = Color.white;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
tmp.font = defaultFont;
}
return textObj;
}
private static GameObject CreateToggle(string name, Transform parent, string labelText)
{
GameObject toggleObj = new GameObject(name);
toggleObj.transform.SetParent(parent, false);
RectTransform rect = toggleObj.AddComponent<RectTransform>();
rect.sizeDelta = new Vector2(160, 60);
// Background
Image bgImg = toggleObj.AddComponent<Image>();
bgImg.color = new Color(0.2f, 0.2f, 0.2f, 1f);
Toggle toggle = toggleObj.AddComponent<Toggle>();
toggle.isOn = true;
toggle.transition = Selectable.Transition.ColorTint;
// Checkmark Background
GameObject checkmarkBg = new GameObject("Background");
checkmarkBg.transform.SetParent(toggleObj.transform, false);
RectTransform checkmarkBgRect = checkmarkBg.AddComponent<RectTransform>();
checkmarkBgRect.anchorMin = new Vector2(0, 0.5f);
checkmarkBgRect.anchorMax = new Vector2(0, 0.5f);
checkmarkBgRect.pivot = new Vector2(0, 0.5f);
checkmarkBgRect.sizeDelta = new Vector2(40, 40);
checkmarkBgRect.anchoredPosition = new Vector2(10, 0);
Image checkmarkBgImg = checkmarkBg.AddComponent<Image>();
checkmarkBgImg.color = new Color(0.8f, 0.8f, 0.8f, 1f);
// Checkmark
GameObject checkmark = new GameObject("Checkmark");
checkmark.transform.SetParent(checkmarkBg.transform, false);
RectTransform checkmarkRect = checkmark.AddComponent<RectTransform>();
checkmarkRect.anchorMin = Vector2.zero;
checkmarkRect.anchorMax = Vector2.one;
checkmarkRect.sizeDelta = new Vector2(-10, -10);
Image checkmarkImg = checkmark.AddComponent<Image>();
checkmarkImg.color = new Color(0.2f, 0.8f, 0.2f, 1f);
toggle.targetGraphic = checkmarkBgImg;
toggle.graphic = checkmarkImg;
// Label
GameObject label = new GameObject("Label");
label.transform.SetParent(toggleObj.transform, false);
RectTransform labelRect = label.AddComponent<RectTransform>();
labelRect.anchorMin = new Vector2(0, 0);
labelRect.anchorMax = new Vector2(1, 1);
labelRect.offsetMin = new Vector2(60, 0);
labelRect.offsetMax = new Vector2(-10, 0);
TextMeshProUGUI labelTmp = label.AddComponent<TextMeshProUGUI>();
labelTmp.text = labelText;
labelTmp.fontSize = 24;
labelTmp.alignment = TextAlignmentOptions.MidlineLeft;
labelTmp.color = Color.white;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
labelTmp.font = defaultFont;
}
return toggleObj;
}
private static GameObject CreateConsoleLogItemPrefab()
{
GameObject logItem = new GameObject("ConsoleLogItem");
RectTransform rect = logItem.AddComponent<RectTransform>();
// 设置锚点为水平拉伸,顶部对齐
rect.anchorMin = new Vector2(0, 1);
rect.anchorMax = new Vector2(1, 1);
rect.pivot = new Vector2(0.5f, 1);
// 设置固定高度50宽度自动拉伸
rect.sizeDelta = new Vector2(0, 50);
// 添加LayoutElement来确保布局组件正确控制尺寸
LayoutElement layoutElement = logItem.AddComponent<LayoutElement>();
layoutElement.minHeight = 50;
layoutElement.preferredHeight = 50;
layoutElement.flexibleWidth = 1;
// Toggle组件
Toggle toggle = logItem.AddComponent<Toggle>();
toggle.isOn = false;
toggle.transition = Selectable.Transition.ColorTint;
// Background
GameObject background = new GameObject("Background");
background.transform.SetParent(logItem.transform, false);
RectTransform bgRect = background.AddComponent<RectTransform>();
bgRect.anchorMin = Vector2.zero;
bgRect.anchorMax = Vector2.one;
bgRect.sizeDelta = Vector2.zero;
Image bgImg = background.AddComponent<Image>();
bgImg.color = new Color(0.12f, 0.12f, 0.12f, 1f);
toggle.targetGraphic = bgImg;
// Label (日志文本)
GameObject label = new GameObject("Label");
label.transform.SetParent(logItem.transform, false);
RectTransform labelRect = label.AddComponent<RectTransform>();
labelRect.anchorMin = Vector2.zero;
labelRect.anchorMax = Vector2.one;
labelRect.offsetMin = new Vector2(10, 5);
labelRect.offsetMax = new Vector2(-10, -5);
TextMeshProUGUI labelTmp = label.AddComponent<TextMeshProUGUI>();
labelTmp.fontSize = 28;
labelTmp.alignment = TextAlignmentOptions.MidlineLeft;
labelTmp.color = Color.white;
labelTmp.overflowMode = TextOverflowModes.Truncate;
labelTmp.richText = true;
labelTmp.enableWordWrapping = false;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
labelTmp.font = defaultFont;
}
// 设置ColorBlock以支持选中状态
ColorBlock colors = toggle.colors;
colors.normalColor = new Color(0.12f, 0.12f, 0.12f, 1f);
colors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1f);
colors.selectedColor = new Color(0.25f, 0.35f, 0.45f, 1f);
colors.pressedColor = new Color(0.15f, 0.15f, 0.15f, 1f);
toggle.colors = colors;
// 不需要设置为不激活因为Instantiate时会继承这个状态
// 而且作为模板时不会显示在场景中
// 不销毁预制件
Object.DontDestroyOnLoad(logItem);
Debug.Log("[RuntimeUIGenerator] Created ConsoleLogItem prefab");
return logItem;
}
private static GameObject CreateInputField(string name, Transform parent, string placeholder)
{
GameObject inputObj = new GameObject(name);
inputObj.transform.SetParent(parent, false);
RectTransform rect = inputObj.AddComponent<RectTransform>();
rect.sizeDelta = new Vector2(600, 80);
Image img = inputObj.AddComponent<Image>();
img.color = new Color(0.15f, 0.15f, 0.15f, 1f);
TMP_InputField input = inputObj.AddComponent<TMP_InputField>();
GameObject textArea = new GameObject("TextArea");
textArea.transform.SetParent(inputObj.transform, false);
RectTransform taRect = textArea.AddComponent<RectTransform>();
taRect.anchorMin = Vector2.zero;
taRect.anchorMax = Vector2.one;
taRect.sizeDelta = Vector2.zero;
taRect.offsetMin = new Vector2(10, 10);
taRect.offsetMax = new Vector2(-10, -10);
GameObject textObj = new GameObject("Text");
textObj.transform.SetParent(textArea.transform, false);
RectTransform textRect = textObj.AddComponent<RectTransform>();
textRect.anchorMin = Vector2.zero;
textRect.anchorMax = Vector2.one;
textRect.sizeDelta = Vector2.zero;
TextMeshProUGUI text = textObj.AddComponent<TextMeshProUGUI>();
text.fontSize = 32;
text.color = Color.white;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
text.font = defaultFont;
}
GameObject placeholderObj = new GameObject("Placeholder");
placeholderObj.transform.SetParent(textArea.transform, false);
RectTransform phRect = placeholderObj.AddComponent<RectTransform>();
phRect.anchorMin = Vector2.zero;
phRect.anchorMax = Vector2.one;
phRect.sizeDelta = Vector2.zero;
TextMeshProUGUI phText = placeholderObj.AddComponent<TextMeshProUGUI>();
phText.text = placeholder;
phText.fontSize = 32;
phText.color = new Color(1, 1, 1, 0.5f);
// 设置默认字体
if (defaultFont != null)
{
phText.font = defaultFont;
}
input.textViewport = taRect;
input.textComponent = text;
input.placeholder = phText;
return inputObj;
}
private static GameObject CreateSlider(string name, Transform parent)
{
GameObject sliderObj = new GameObject(name);
sliderObj.transform.SetParent(parent, false);
RectTransform rect = sliderObj.AddComponent<RectTransform>();
rect.sizeDelta = new Vector2(800, 60);
Slider slider = sliderObj.AddComponent<Slider>();
slider.minValue = 0;
slider.maxValue = 300;
slider.value = 60;
// Background
GameObject bg = new GameObject("Background");
bg.transform.SetParent(sliderObj.transform, false);
RectTransform bgRect = bg.AddComponent<RectTransform>();
bgRect.anchorMin = Vector2.zero;
bgRect.anchorMax = Vector2.one;
bgRect.sizeDelta = Vector2.zero;
bg.AddComponent<Image>().color = new Color(0.2f, 0.2f, 0.2f, 1f);
// Fill Area
GameObject fillArea = new GameObject("Fill Area");
fillArea.transform.SetParent(sliderObj.transform, false);
RectTransform faRect = fillArea.AddComponent<RectTransform>();
faRect.anchorMin = Vector2.zero;
faRect.anchorMax = Vector2.one;
faRect.sizeDelta = Vector2.zero;
GameObject fill = new GameObject("Fill");
fill.transform.SetParent(fillArea.transform, false);
RectTransform fillRect = fill.AddComponent<RectTransform>();
fillRect.anchorMin = Vector2.zero;
fillRect.anchorMax = Vector2.one;
fillRect.sizeDelta = Vector2.zero;
fill.AddComponent<Image>().color = new Color(0.2f, 0.6f, 1f, 1f);
slider.fillRect = fillRect;
// Handle
GameObject handleArea = new GameObject("Handle Slide Area");
handleArea.transform.SetParent(sliderObj.transform, false);
RectTransform haRect = handleArea.AddComponent<RectTransform>();
haRect.anchorMin = Vector2.zero;
haRect.anchorMax = Vector2.one;
haRect.sizeDelta = Vector2.zero;
GameObject handle = new GameObject("Handle");
handle.transform.SetParent(handleArea.transform, false);
RectTransform handleRect = handle.AddComponent<RectTransform>();
handleRect.sizeDelta = new Vector2(40, 60);
handle.AddComponent<Image>().color = Color.white;
slider.handleRect = handleRect;
slider.targetGraphic = handle.GetComponent<Image>();
return sliderObj;
}
private static GameObject CreateCustomButtonPrefab()
{
// 创建一个隐藏的临时父对象来存放预制件模板
GameObject tempParent = new GameObject("_TempPrefabHolder");
tempParent.SetActive(false);
Object.DontDestroyOnLoad(tempParent);
GameObject btn = CreateButton("CustomButton", tempParent.transform, "按钮");
btn.GetComponent<RectTransform>().sizeDelta = new Vector2(280, 90);
// 确保预制件的TextMeshProUGUI也能被SetSDF设置
// 通过将其标记到特殊层或添加特殊标签
btn.tag = "Untagged"; // 保持默认,确保能被找到
return btn;
}
private static GameObject CreateTabButtonPrefab()
{
// 使用同一个临时父对象
GameObject tempParent = GameObject.Find("_TempPrefabHolder");
if (tempParent == null)
{
tempParent = new GameObject("_TempPrefabHolder");
tempParent.SetActive(false);
Object.DontDestroyOnLoad(tempParent);
}
GameObject btn = CreateButton("TabButton", tempParent.transform, "标签");
btn.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 80);
// 确保预制件的TextMeshProUGUI也能被SetSDF设置
btn.tag = "Untagged"; // 保持默认,确保能被找到
return btn;
}
/// <summary>
/// 确保场景中有EventSystem如果没有则创建一个
/// </summary>
private static void EnsureEventSystem()
{
EventSystem eventSystem = Object.FindObjectOfType<EventSystem>();
if (eventSystem == null)
{
GameObject eventSystemObj = new GameObject("EventSystem");
eventSystem = eventSystemObj.AddComponent<EventSystem>();
eventSystemObj.AddComponent<StandaloneInputModule>();
Object.DontDestroyOnLoad(eventSystemObj);
Debug.Log("[RuntimeUIGenerator] 已自动创建EventSystem");
}
else
{
Debug.Log("[RuntimeUIGenerator] EventSystem已存在");
}
}
private static void SetupReferences(UniversalDebugTool tool, Canvas canvas, GameObject mainWindow,
GameObject floatingButton, GameObject parametersPage, GameObject customButtonsPage,
GameObject toolbarPage, GameObject settingsPage, GameObject consolePage, GameObject inputDialog)
{
// 使用反射设置私有字段
var type = typeof(UniversalDebugTool);
var flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
// 主窗口
type.GetField("mainWindow", flags)?.SetValue(tool, mainWindow.GetComponent<RectTransform>());
type.GetField("canvas", flags)?.SetValue(tool, canvas);
type.GetField("tabButtonContainer", flags)?.SetValue(tool, mainWindow.transform.Find("TabButtonContainer").GetComponent<RectTransform>());
type.GetField("contentContainer", flags)?.SetValue(tool, mainWindow.transform.Find("ContentContainer").GetComponent<RectTransform>());
type.GetField("closeButton", flags)?.SetValue(tool, mainWindow.transform.Find("CloseButton").GetComponent<Button>());
// 悬浮按钮
type.GetField("floatingButton", flags)?.SetValue(tool, floatingButton);
type.GetField("draggableComponent", flags)?.SetValue(tool, floatingButton.GetComponent<DraggableFloatingButton>());
// 参数查看页面
type.GetField("parametersPage", flags)?.SetValue(tool, parametersPage);
type.GetField("deviceInfoText", flags)?.SetValue(tool, parametersPage.transform.Find("Viewport/Content/DeviceInfo").GetComponent<TextMeshProUGUI>());
type.GetField("systemInfoText", flags)?.SetValue(tool, parametersPage.transform.Find("Viewport/Content/SystemInfo").GetComponent<TextMeshProUGUI>());
type.GetField("parametersScrollRect", flags)?.SetValue(tool, parametersPage.GetComponent<ScrollRect>());
// 自定义按钮页面
type.GetField("customButtonsPage", flags)?.SetValue(tool, customButtonsPage);
type.GetField("buttonContainer", flags)?.SetValue(tool, customButtonsPage.transform.Find("Viewport/ButtonContainer").GetComponent<RectTransform>());
type.GetField("buttonsScrollRect", flags)?.SetValue(tool, customButtonsPage.GetComponent<ScrollRect>());
// 创建按钮预制件
GameObject buttonPrefab = CreateCustomButtonPrefab();
GameObject tabButtonPrefab = CreateTabButtonPrefab();
type.GetField("buttonPrefab", flags)?.SetValue(tool, buttonPrefab);
type.GetField("tabButtonPrefab", flags)?.SetValue(tool, tabButtonPrefab);
// 工具栏页面
type.GetField("toolbarPage", flags)?.SetValue(tool, toolbarPage);
Transform toolbarPanel = toolbarPage.transform.Find("TimeAdjustPanel");
if (toolbarPanel != null)
{
type.GetField("timeAdjustSlider", flags)?.SetValue(tool, toolbarPanel.Find("TimeAdjustSlider")?.GetComponent<Slider>());
type.GetField("timeAdjustValueText", flags)?.SetValue(tool, toolbarPanel.Find("TimeAdjustValueText")?.GetComponent<TextMeshProUGUI>());
Transform btnContainer = toolbarPanel.Find("ButtonContainer");
if (btnContainer != null)
{
type.GetField("timeIncreaseButton", flags)?.SetValue(tool, btnContainer.Find("TimeIncreaseButton")?.GetComponent<Button>());
type.GetField("timeDecreaseButton", flags)?.SetValue(tool, btnContainer.Find("TimeDecreaseButton")?.GetComponent<Button>());
}
}
// 设置页面
type.GetField("settingsPage", flags)?.SetValue(tool, settingsPage);
Transform resPanel = settingsPage.transform.Find("ResolutionPanel");
if (resPanel != null)
{
Transform inputContainer = resPanel.Find("InputContainer");
if (inputContainer != null)
{
type.GetField("widthInputField", flags)?.SetValue(tool, inputContainer.Find("WidthInputField")?.GetComponent<TMP_InputField>());
type.GetField("heightInputField", flags)?.SetValue(tool, inputContainer.Find("HeightInputField")?.GetComponent<TMP_InputField>());
}
Transform btnContainer = resPanel.Find("ButtonContainer");
if (btnContainer != null)
{
type.GetField("applyResolutionButton", flags)?.SetValue(tool, btnContainer.Find("ApplyResolutionButton")?.GetComponent<Button>());
type.GetField("resetResolutionButton", flags)?.SetValue(tool, btnContainer.Find("ResetResolutionButton")?.GetComponent<Button>());
}
type.GetField("currentResolutionText", flags)?.SetValue(tool, resPanel.Find("CurrentResolutionText")?.GetComponent<TextMeshProUGUI>());
}
// 控制台页面
type.GetField("consolePage", flags)?.SetValue(tool, consolePage);
type.GetField("consoleLogScrollRect", flags)?.SetValue(tool, consolePage.transform.Find("LogArea/ConsoleLogScrollView")?.GetComponent<ScrollRect>());
type.GetField("consoleLogContent", flags)?.SetValue(tool, consolePage.transform.Find("LogArea/ConsoleLogScrollView/Viewport/ConsoleLogContent")?.GetComponent<RectTransform>());
type.GetField("consoleDetailScrollRect", flags)?.SetValue(tool, consolePage.transform.Find("DetailArea/ConsoleDetailScrollView")?.GetComponent<ScrollRect>());
type.GetField("consoleDetailText", flags)?.SetValue(tool, consolePage.transform.Find("DetailArea/ConsoleDetailScrollView/Viewport/Content/ConsoleDetailText")?.GetComponent<TextMeshProUGUI>());
Transform controlPanel = consolePage.transform.Find("ControlPanel");
if (controlPanel != null)
{
type.GetField("consoleClearButton", flags)?.SetValue(tool, controlPanel.Find("ConsoleClearButton")?.GetComponent<Button>());
type.GetField("consoleLockScrollToggle", flags)?.SetValue(tool, controlPanel.Find("ConsoleLockScrollToggle")?.GetComponent<Toggle>());
type.GetField("consoleInfoFilterToggle", flags)?.SetValue(tool, controlPanel.Find("ConsoleInfoFilterToggle")?.GetComponent<Toggle>());
type.GetField("consoleWarningFilterToggle", flags)?.SetValue(tool, controlPanel.Find("ConsoleWarningFilterToggle")?.GetComponent<Toggle>());
type.GetField("consoleErrorFilterToggle", flags)?.SetValue(tool, controlPanel.Find("ConsoleErrorFilterToggle")?.GetComponent<Toggle>());
type.GetField("consoleFatalFilterToggle", flags)?.SetValue(tool, controlPanel.Find("ConsoleFatalFilterToggle")?.GetComponent<Toggle>());
}
// 创建日志项预制件
GameObject consoleLogItemPrefab = CreateConsoleLogItemPrefab();
type.GetField("consoleLogItemPrefab", flags)?.SetValue(tool, consoleLogItemPrefab);
// 输入对话框
type.GetField("inputDialog", flags)?.SetValue(tool, inputDialog);
Transform dialogPanel = inputDialog.transform.Find("Panel");
if (dialogPanel != null)
{
type.GetField("inputDialogTitle", flags)?.SetValue(tool, dialogPanel.Find("Title")?.GetComponent<TextMeshProUGUI>());
type.GetField("inputDialogInputField", flags)?.SetValue(tool, dialogPanel.Find("InputField")?.GetComponent<TMP_InputField>());
Transform btnContainer = dialogPanel.Find("ButtonContainer");
if (btnContainer != null)
{
type.GetField("inputDialogConfirmBtn", flags)?.SetValue(tool, btnContainer.Find("ConfirmButton")?.GetComponent<Button>());
type.GetField("inputDialogCancelBtn", flags)?.SetValue(tool, btnContainer.Find("CancelButton")?.GetComponent<Button>());
}
}
Debug.Log("[RuntimeUIGenerator] 所有引用已设置完成");
}
#endregion
}
}