MeowmentDebugTool/Packages/com.bywaystudios.meowmentdebugtool/Runtime/RuntimeUIGenerator.cs
2026-02-03 10:32:06 +08:00

1724 lines
88 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 customCheckBoxesPage = CreateCustomCheckBoxesPage(contentContainer.transform);
GameObject customValuesPage = CreateCustomValuesPage(contentContainer.transform);
GameObject settingsPage = CreateSettingsPage(contentContainer.transform);
GameObject consolePage = CreateConsolePage(contentContainer.transform);
// 创建输入对话框
GameObject inputDialog = CreateInputDialog(canvasObj.transform);
// 设置引用
SetupReferences(tool, canvas, mainWindow, floatingButton,
parametersPage, customButtonsPage, customCheckBoxesPage, customValuesPage, 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, 1);
rect.anchorMax = new Vector2(0, 1);
rect.pivot = new Vector2(0, 1);
rect.sizeDelta = new Vector2(90, 90);
// 距离左上角边缘10像素
rect.anchoredPosition = new Vector2(10, -10);
Image img = floatBtn.AddComponent<Image>();
img.color = new Color(0.2f, 0.6f, 1f, 0.8f);
img.raycastTarget = true; // 确保可以接收点击事件
// 不再添加Button组件点击事件由DraggableFloatingButton的OnPointerClick处理
// 添加文本
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 = 28;
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>();
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 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);
containerRect.offsetMin = new Vector2(0, containerRect.offsetMin.y);
containerRect.offsetMax = new Vector2(0, containerRect.offsetMax.y);
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 CreateCustomCheckBoxesPage(Transform parent)
{
GameObject page = new GameObject("CustomCheckBoxesPage");
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 checkBoxContainer = new GameObject("CheckBoxContainer");
checkBoxContainer.transform.SetParent(viewport.transform, false);
RectTransform containerRect = checkBoxContainer.AddComponent<RectTransform>();
containerRect.anchorMin = new Vector2(0, 1);
containerRect.anchorMax = new Vector2(1, 1);
containerRect.pivot = new Vector2(0.5f, 1);
containerRect.offsetMin = new Vector2(0, containerRect.offsetMin.y); // left = 0
containerRect.offsetMax = new Vector2(0, containerRect.offsetMax.y); // right = 0
// 使用垂直布局,一行一个复选框
VerticalLayoutGroup vertLayout = checkBoxContainer.AddComponent<VerticalLayoutGroup>();
vertLayout.spacing = 15;
vertLayout.padding = new RectOffset(20, 20, 20, 20);
vertLayout.childControlWidth = true;
vertLayout.childControlHeight = false;
vertLayout.childForceExpandWidth = true;
ContentSizeFitter fitter = checkBoxContainer.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
scroll.viewport = vpRect;
scroll.content = containerRect;
return page;
}
private static GameObject CreateCustomValuesPage(Transform parent)
{
GameObject page = new GameObject("CustomValuesPage");
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 valueContainer = new GameObject("ValueContainer");
valueContainer.transform.SetParent(viewport.transform, false);
RectTransform containerRect = valueContainer.AddComponent<RectTransform>();
containerRect.anchorMin = new Vector2(0, 1);
containerRect.anchorMax = new Vector2(1, 1);
containerRect.pivot = new Vector2(0.5f, 1);
containerRect.offsetMin = new Vector2(0, containerRect.offsetMin.y); // left = 0
containerRect.offsetMax = new Vector2(0, containerRect.offsetMax.y); // right = 0
// 使用垂直布局,一行一个数值项
VerticalLayoutGroup vertLayout = valueContainer.AddComponent<VerticalLayoutGroup>();
vertLayout.spacing = 20;
vertLayout.padding = new RectOffset(20, 20, 20, 20);
vertLayout.childControlWidth = true;
vertLayout.childControlHeight = false;
vertLayout.childForceExpandWidth = true;
ContentSizeFitter fitter = valueContainer.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);
// Console Log缓存池设置面板
GameObject bufferPanel = new GameObject("BufferPanel");
bufferPanel.transform.SetParent(page.transform, false);
RectTransform bufferPanelRect = bufferPanel.AddComponent<RectTransform>();
bufferPanelRect.anchorMin = new Vector2(0, 0);
bufferPanelRect.anchorMax = new Vector2(1, 0.5f);
bufferPanelRect.offsetMin = new Vector2(20, 20);
bufferPanelRect.offsetMax = new Vector2(-20, 0);
VerticalLayoutGroup bufferVLayout = bufferPanel.AddComponent<VerticalLayoutGroup>();
bufferVLayout.spacing = 30;
bufferVLayout.padding = new RectOffset(40, 40, 40, 40);
bufferVLayout.childControlWidth = true;
bufferVLayout.childControlHeight = false;
bufferVLayout.childForceExpandWidth = true;
// 标题
GameObject bufferTitle = CreateTextObject("BufferTitle", bufferPanel.transform, "Console Log缓存池设置");
bufferTitle.GetComponent<TextMeshProUGUI>().fontSize = 36;
bufferTitle.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Center;
bufferTitle.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 60);
// Info缓存池输入
GameObject infoBufferContainer = new GameObject("InfoBufferContainer");
infoBufferContainer.transform.SetParent(bufferPanel.transform, false);
RectTransform infoBufferRect = infoBufferContainer.AddComponent<RectTransform>();
infoBufferRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup infoBufferHLayout = infoBufferContainer.AddComponent<HorizontalLayoutGroup>();
infoBufferHLayout.spacing = 20;
infoBufferHLayout.childControlWidth = true;
infoBufferHLayout.childControlHeight = true;
infoBufferHLayout.childForceExpandWidth = false;
infoBufferHLayout.childForceExpandHeight = true;
GameObject infoLabel = CreateTextObject("InfoLabel", infoBufferContainer.transform, "Info:");
infoLabel.GetComponent<TextMeshProUGUI>().fontSize = 28;
infoLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 100);
GameObject infoBufferInput = CreateInputField("InfoBufferInputField", infoBufferContainer.transform, "50");
infoBufferInput.GetComponent<RectTransform>().sizeDelta = new Vector2(300, 100);
// Warning缓存池输入
GameObject warningBufferContainer = new GameObject("WarningBufferContainer");
warningBufferContainer.transform.SetParent(bufferPanel.transform, false);
RectTransform warningBufferRect = warningBufferContainer.AddComponent<RectTransform>();
warningBufferRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup warningBufferHLayout = warningBufferContainer.AddComponent<HorizontalLayoutGroup>();
warningBufferHLayout.spacing = 20;
warningBufferHLayout.childControlWidth = true;
warningBufferHLayout.childControlHeight = true;
warningBufferHLayout.childForceExpandWidth = false;
warningBufferHLayout.childForceExpandHeight = true;
GameObject warningLabel = CreateTextObject("WarningLabel", warningBufferContainer.transform, "Warning:");
warningLabel.GetComponent<TextMeshProUGUI>().fontSize = 28;
warningLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 100);
GameObject warningBufferInput = CreateInputField("WarningBufferInputField", warningBufferContainer.transform, "50");
warningBufferInput.GetComponent<RectTransform>().sizeDelta = new Vector2(300, 100);
// Error缓存池输入
GameObject errorBufferContainer = new GameObject("ErrorBufferContainer");
errorBufferContainer.transform.SetParent(bufferPanel.transform, false);
RectTransform errorBufferRect = errorBufferContainer.AddComponent<RectTransform>();
errorBufferRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup errorBufferHLayout = errorBufferContainer.AddComponent<HorizontalLayoutGroup>();
errorBufferHLayout.spacing = 20;
errorBufferHLayout.childControlWidth = true;
errorBufferHLayout.childControlHeight = true;
errorBufferHLayout.childForceExpandWidth = false;
errorBufferHLayout.childForceExpandHeight = true;
GameObject errorLabel = CreateTextObject("ErrorLabel", errorBufferContainer.transform, "Error:");
errorLabel.GetComponent<TextMeshProUGUI>().fontSize = 28;
errorLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 100);
GameObject errorBufferInput = CreateInputField("ErrorBufferInputField", errorBufferContainer.transform, "50");
errorBufferInput.GetComponent<RectTransform>().sizeDelta = new Vector2(300, 100);
// Fatal缓存池输入
GameObject fatalBufferContainer = new GameObject("FatalBufferContainer");
fatalBufferContainer.transform.SetParent(bufferPanel.transform, false);
RectTransform fatalBufferRect = fatalBufferContainer.AddComponent<RectTransform>();
fatalBufferRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup fatalBufferHLayout = fatalBufferContainer.AddComponent<HorizontalLayoutGroup>();
fatalBufferHLayout.spacing = 20;
fatalBufferHLayout.childControlWidth = true;
fatalBufferHLayout.childControlHeight = true;
fatalBufferHLayout.childForceExpandWidth = false;
fatalBufferHLayout.childForceExpandHeight = true;
GameObject fatalLabel = CreateTextObject("FatalLabel", fatalBufferContainer.transform, "Fatal:");
fatalLabel.GetComponent<TextMeshProUGUI>().fontSize = 28;
fatalLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 100);
GameObject fatalBufferInput = CreateInputField("FatalBufferInputField", fatalBufferContainer.transform, "50");
fatalBufferInput.GetComponent<RectTransform>().sizeDelta = new Vector2(300, 100);
// 缓存池按钮容器
GameObject bufferBtnContainer = new GameObject("BufferButtonContainer");
bufferBtnContainer.transform.SetParent(bufferPanel.transform, false);
RectTransform bufferBtnRect = bufferBtnContainer.AddComponent<RectTransform>();
bufferBtnRect.sizeDelta = new Vector2(0, 100);
HorizontalLayoutGroup bufferBtnLayout = bufferBtnContainer.AddComponent<HorizontalLayoutGroup>();
bufferBtnLayout.spacing = 20;
bufferBtnLayout.childControlWidth = true;
bufferBtnLayout.childControlHeight = true;
bufferBtnLayout.childForceExpandWidth = true;
bufferBtnLayout.childForceExpandHeight = true;
GameObject applyBufferBtn = CreateButton("ApplyBufferButton", bufferBtnContainer.transform, "应用");
GameObject resetBufferBtn = CreateButton("ResetBufferButton", bufferBtnContainer.transform, "重置");
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;
// 文字筛选面板
GameObject textFilterPanel = new GameObject("TextFilterPanel");
textFilterPanel.transform.SetParent(page.transform, false);
RectTransform textFilterRect = textFilterPanel.AddComponent<RectTransform>();
textFilterRect.sizeDelta = new Vector2(0, 120);
LayoutElement textFilterLayout = textFilterPanel.AddComponent<LayoutElement>();
textFilterLayout.preferredHeight = 120;
textFilterLayout.flexibleHeight = 0;
HorizontalLayoutGroup textFilterHLayout = textFilterPanel.AddComponent<HorizontalLayoutGroup>();
textFilterHLayout.spacing = 20;
textFilterHLayout.padding = new RectOffset(10, 10, 10, 10);
textFilterHLayout.childControlWidth = true;
textFilterHLayout.childControlHeight = true;
textFilterHLayout.childForceExpandWidth = true;
textFilterHLayout.childForceExpandHeight = true;
// 文字筛选标签
GameObject textFilterLabel = CreateTextObject("TextFilterLabel", textFilterPanel.transform, "文字筛选:");
textFilterLabel.GetComponent<TextMeshProUGUI>().fontSize = 28;
textFilterLabel.GetComponent<TextMeshProUGUI>().alignment = TextAlignmentOptions.Left;
textFilterLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 0);
LayoutElement labelLayout = textFilterLabel.AddComponent<LayoutElement>();
labelLayout.preferredWidth = 200;
labelLayout.flexibleWidth = 0;
// 文字筛选输入框
GameObject textFilterInput = CreateInputField("ConsoleTextFilterInputField", textFilterPanel.transform, "");
textFilterInput.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 100);
TMP_InputField inputField = textFilterInput.GetComponent<TMP_InputField>();
if (inputField != null && inputField.placeholder is TextMeshProUGUI placeholder)
{
placeholder.text = "输入筛选文字...";
}
// 日志区域 (60%)
GameObject logArea = new GameObject("LogArea");
logArea.transform.SetParent(page.transform, false);
RectTransform logAreaRect = logArea.AddComponent<RectTransform>();
logAreaRect.sizeDelta = new Vector2(0, 1180);
LayoutElement logAreaLayout = logArea.AddComponent<LayoutElement>();
logAreaLayout.preferredHeight = 1180;
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(0, 100);
detailContentRect.anchoredPosition = Vector2.zero;
// 为 Content 添加 ContentSizeFitter 以自动调整高度
ContentSizeFitter contentFitter = detailContent.AddComponent<ContentSizeFitter>();
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// 添加 VerticalLayoutGroup 用于布局
VerticalLayoutGroup contentLayout = detailContent.AddComponent<VerticalLayoutGroup>();
contentLayout.childControlHeight = false;
contentLayout.childControlWidth = true;
contentLayout.childForceExpandHeight = false;
contentLayout.childForceExpandWidth = true;
contentLayout.padding = new RectOffset(10, 10, 10, 10);
// 详情文本
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 使其根据内容自动调整大小
ContentSizeFitter detailTextFitter = detailText.AddComponent<ContentSizeFitter>();
detailTextFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// 添加 LayoutElement 使文本在 VerticalLayoutGroup 中正确工作
LayoutElement detailTextLayout = detailText.AddComponent<LayoutElement>();
detailTextLayout.flexibleHeight = 0;
detailTextLayout.preferredHeight = -1;
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;
}
private static GameObject CreateCustomCheckBoxPrefab()
{
// 使用同一个临时父对象
GameObject tempParent = GameObject.Find("_TempPrefabHolder");
if (tempParent == null)
{
tempParent = new GameObject("_TempPrefabHolder");
tempParent.SetActive(false);
Object.DontDestroyOnLoad(tempParent);
}
GameObject toggleObj = new GameObject("CustomCheckBox", typeof(RectTransform));
toggleObj.transform.SetParent(tempParent.transform, false);
RectTransform rect = toggleObj.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(800, 80);
// 添加背景图片
Image bg = toggleObj.AddComponent<Image>();
bg.color = new Color(0.15f, 0.15f, 0.15f, 1f);
// 创建复选框背景(左侧)
GameObject checkboxBg = new GameObject("Background");
checkboxBg.transform.SetParent(toggleObj.transform, false);
RectTransform checkboxBgRect = checkboxBg.AddComponent<RectTransform>();
checkboxBgRect.anchorMin = new Vector2(0, 0.5f);
checkboxBgRect.anchorMax = new Vector2(0, 0.5f);
checkboxBgRect.pivot = new Vector2(0, 0.5f);
checkboxBgRect.anchoredPosition = new Vector2(20, 0);
checkboxBgRect.sizeDelta = new Vector2(60, 60);
Image checkboxBgImage = checkboxBg.AddComponent<Image>();
checkboxBgImage.color = new Color(0.8f, 0.8f, 0.8f, 1f);
// 创建勾选标记
GameObject checkmark = new GameObject("Checkmark");
checkmark.transform.SetParent(checkboxBg.transform, false);
RectTransform checkmarkRect = checkmark.AddComponent<RectTransform>();
checkmarkRect.anchorMin = Vector2.zero;
checkmarkRect.anchorMax = Vector2.one;
checkmarkRect.sizeDelta = Vector2.zero;
Image checkmarkImage = checkmark.AddComponent<Image>();
checkmarkImage.color = new Color(0.2f, 0.8f, 0.2f, 1f);
// 创建文本标签(右侧)
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.pivot = new Vector2(0, 0.5f);
labelRect.offsetMin = new Vector2(100, 0);
labelRect.offsetMax = new Vector2(-20, 0);
TextMeshProUGUI labelText = label.AddComponent<TextMeshProUGUI>();
labelText.text = "复选框";
labelText.fontSize = 32;
labelText.alignment = TextAlignmentOptions.Left;
labelText.color = Color.white;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
labelText.font = defaultFont;
}
// 添加Toggle组件
Toggle toggle = toggleObj.AddComponent<Toggle>();
toggle.targetGraphic = checkboxBgImage;
toggle.graphic = checkmarkImage;
toggle.isOn = false;
return toggleObj;
}
private static GameObject CreateCustomValuePrefab()
{
// 使用同一个临时父对象
GameObject tempParent = GameObject.Find("_TempPrefabHolder");
if (tempParent == null)
{
tempParent = new GameObject("_TempPrefabHolder");
tempParent.SetActive(false);
Object.DontDestroyOnLoad(tempParent);
}
GameObject valueObj = new GameObject("CustomValue", typeof(RectTransform));
valueObj.transform.SetParent(tempParent.transform, false);
RectTransform rect = valueObj.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(900, 140);
// 添加背景图片
Image bg = valueObj.AddComponent<Image>();
bg.color = new Color(0.15f, 0.15f, 0.15f, 1f);
// 创建标签文本(顶部独占一行)
GameObject label = new GameObject("Label");
label.transform.SetParent(valueObj.transform, false);
RectTransform labelRect = label.AddComponent<RectTransform>();
labelRect.anchorMin = new Vector2(0, 1);
labelRect.anchorMax = new Vector2(1, 1);
labelRect.pivot = new Vector2(0, 1);
labelRect.anchoredPosition = new Vector2(20, -10);
labelRect.sizeDelta = new Vector2(-40, 35);
TextMeshProUGUI labelText = label.AddComponent<TextMeshProUGUI>();
labelText.text = "数值名称";
labelText.fontSize = 28;
labelText.alignment = TextAlignmentOptions.Left;
labelText.color = Color.white;
// 设置默认字体
TMP_FontAsset defaultFont = GetDefaultFont();
if (defaultFont != null)
{
labelText.font = defaultFont;
}
// 创建滑动条标题下方占据左侧60%
GameObject sliderObj = new GameObject("Slider");
sliderObj.transform.SetParent(valueObj.transform, false);
RectTransform sliderRect = sliderObj.AddComponent<RectTransform>();
sliderRect.anchorMin = new Vector2(0, 0);
sliderRect.anchorMax = new Vector2(0.55f, 0);
sliderRect.pivot = new Vector2(0, 0);
sliderRect.anchoredPosition = new Vector2(20, 15);
sliderRect.sizeDelta = new Vector2(-20, 50);
Slider slider = sliderObj.AddComponent<Slider>();
// 滑动条背景
GameObject sliderBg = new GameObject("Background");
sliderBg.transform.SetParent(sliderObj.transform, false);
RectTransform sliderBgRect = sliderBg.AddComponent<RectTransform>();
sliderBgRect.anchorMin = Vector2.zero;
sliderBgRect.anchorMax = Vector2.one;
sliderBgRect.sizeDelta = Vector2.zero;
Image sliderBgImage = sliderBg.AddComponent<Image>();
sliderBgImage.color = new Color(0.3f, 0.3f, 0.3f, 1f);
// 滑动条填充区域
GameObject fillArea = new GameObject("Fill Area");
fillArea.transform.SetParent(sliderObj.transform, false);
RectTransform fillAreaRect = fillArea.AddComponent<RectTransform>();
fillAreaRect.anchorMin = Vector2.zero;
fillAreaRect.anchorMax = Vector2.one;
fillAreaRect.sizeDelta = new Vector2(-10, -10);
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;
Image fillImage = fill.AddComponent<Image>();
fillImage.color = new Color(0.2f, 0.6f, 1f, 1f);
// 滑动条手柄区域
GameObject handleArea = new GameObject("Handle Slide Area");
handleArea.transform.SetParent(sliderObj.transform, false);
RectTransform handleAreaRect = handleArea.AddComponent<RectTransform>();
handleAreaRect.anchorMin = Vector2.zero;
handleAreaRect.anchorMax = Vector2.one;
handleAreaRect.sizeDelta = new Vector2(-10, 0);
GameObject handle = new GameObject("Handle");
handle.transform.SetParent(handleArea.transform, false);
RectTransform handleRect = handle.AddComponent<RectTransform>();
handleRect.sizeDelta = new Vector2(30, 30);
Image handleImage = handle.AddComponent<Image>();
handleImage.color = Color.white;
slider.fillRect = fillRect;
slider.handleRect = handleRect;
slider.targetGraphic = handleImage;
// 创建输入框(滑动条右侧)
GameObject inputFieldObj = new GameObject("InputField");
inputFieldObj.transform.SetParent(valueObj.transform, false);
RectTransform inputRect = inputFieldObj.AddComponent<RectTransform>();
inputRect.anchorMin = new Vector2(0.56f, 0);
inputRect.anchorMax = new Vector2(0.73f, 0);
inputRect.pivot = new Vector2(0, 0);
inputRect.anchoredPosition = new Vector2(5, 15);
inputRect.sizeDelta = new Vector2(0, 50);
Image inputBg = inputFieldObj.AddComponent<Image>();
inputBg.color = new Color(0.25f, 0.25f, 0.25f, 1f);
// 创建输入框的文本子对象
GameObject inputTextObj = new GameObject("Text");
inputTextObj.transform.SetParent(inputFieldObj.transform, false);
RectTransform inputTextRect = inputTextObj.AddComponent<RectTransform>();
inputTextRect.anchorMin = Vector2.zero;
inputTextRect.anchorMax = Vector2.one;
inputTextRect.sizeDelta = Vector2.zero;
TextMeshProUGUI inputTextComponent = inputTextObj.AddComponent<TextMeshProUGUI>();
inputTextComponent.fontSize = 28;
inputTextComponent.alignment = TextAlignmentOptions.Center;
inputTextComponent.color = Color.white;
TMP_InputField inputField = inputFieldObj.AddComponent<TMP_InputField>();
inputField.textComponent = inputTextComponent;
// 创建确认按钮(输入框右侧)- 手动创建而不是使用CreateButton
GameObject confirmBtn = new GameObject("ConfirmButton", typeof(RectTransform));
confirmBtn.transform.SetParent(valueObj.transform, false);
RectTransform confirmRect = confirmBtn.GetComponent<RectTransform>();
confirmRect.anchorMin = new Vector2(0.74f, 0);
confirmRect.anchorMax = new Vector2(1, 0);
confirmRect.pivot = new Vector2(0, 0);
confirmRect.anchoredPosition = new Vector2(5, 15);
confirmRect.sizeDelta = new Vector2(-20, 50);
Image confirmBtnImage = confirmBtn.AddComponent<Image>();
confirmBtnImage.color = new Color(0.2f, 0.8f, 0.2f, 1f);
Button confirmButton = confirmBtn.AddComponent<Button>();
confirmButton.targetGraphic = confirmBtnImage;
GameObject confirmBtnText = new GameObject("Text");
confirmBtnText.transform.SetParent(confirmBtn.transform, false);
RectTransform confirmBtnTextRect = confirmBtnText.AddComponent<RectTransform>();
confirmBtnTextRect.anchorMin = Vector2.zero;
confirmBtnTextRect.anchorMax = Vector2.one;
confirmBtnTextRect.sizeDelta = Vector2.zero;
TextMeshProUGUI confirmText = confirmBtnText.AddComponent<TextMeshProUGUI>();
confirmText.text = "确认";
confirmText.fontSize = 28;
confirmText.alignment = TextAlignmentOptions.Center;
confirmText.color = Color.white;
return valueObj;
}
/// <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 customCheckBoxesPage, GameObject customValuesPage, 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>());
// 自定义复选框页面
type.GetField("customCheckBoxesPage", flags)?.SetValue(tool, customCheckBoxesPage);
type.GetField("checkBoxContainer", flags)?.SetValue(tool, customCheckBoxesPage.transform.Find("Viewport/CheckBoxContainer").GetComponent<RectTransform>());
type.GetField("checkBoxesScrollRect", flags)?.SetValue(tool, customCheckBoxesPage.GetComponent<ScrollRect>());
// 自定义数值页面
type.GetField("customValuesPage", flags)?.SetValue(tool, customValuesPage);
type.GetField("valueContainer", flags)?.SetValue(tool, customValuesPage.transform.Find("Viewport/ValueContainer").GetComponent<RectTransform>());
type.GetField("valuesScrollRect", flags)?.SetValue(tool, customValuesPage.GetComponent<ScrollRect>());
// 创建按钮、复选框和数值预制件
GameObject buttonPrefab = CreateCustomButtonPrefab();
GameObject checkBoxPrefab = CreateCustomCheckBoxPrefab();
GameObject valuePrefab = CreateCustomValuePrefab();
GameObject tabButtonPrefab = CreateTabButtonPrefab();
type.GetField("buttonPrefab", flags)?.SetValue(tool, buttonPrefab);
type.GetField("checkBoxPrefab", flags)?.SetValue(tool, checkBoxPrefab);
type.GetField("valuePrefab", flags)?.SetValue(tool, valuePrefab);
type.GetField("tabButtonPrefab", flags)?.SetValue(tool, tabButtonPrefab);
// 设置页面
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>());
}
// 设置缓存池大小输入框
Transform bufferPanel = settingsPage.transform.Find("BufferPanel");
if (bufferPanel != null)
{
type.GetField("infoBufferInputField", flags)?.SetValue(tool,
bufferPanel.Find("InfoBufferContainer/InfoBufferInputField")?.GetComponent<TMP_InputField>());
type.GetField("warningBufferInputField", flags)?.SetValue(tool,
bufferPanel.Find("WarningBufferContainer/WarningBufferInputField")?.GetComponent<TMP_InputField>());
type.GetField("errorBufferInputField", flags)?.SetValue(tool,
bufferPanel.Find("ErrorBufferContainer/ErrorBufferInputField")?.GetComponent<TMP_InputField>());
type.GetField("fatalBufferInputField", flags)?.SetValue(tool,
bufferPanel.Find("FatalBufferContainer/FatalBufferInputField")?.GetComponent<TMP_InputField>());
Transform bufferBtnContainer = bufferPanel.Find("BufferButtonContainer");
if (bufferBtnContainer != null)
{
type.GetField("applyBufferButton", flags)?.SetValue(tool, bufferBtnContainer.Find("ApplyBufferButton")?.GetComponent<Button>());
type.GetField("resetBufferButton", flags)?.SetValue(tool, bufferBtnContainer.Find("ResetBufferButton")?.GetComponent<Button>());
}
}
// 控制台页面
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>());
}
// 设置控制台文字筛选输入框
Transform textFilterPanel = consolePage.transform.Find("TextFilterPanel");
if (textFilterPanel != null)
{
type.GetField("consoleTextFilterInputField", flags)?.SetValue(tool,
textFilterPanel.Find("ConsoleTextFilterInputField")?.GetComponent<TMP_InputField>());
}
// 创建日志项预制件
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
}
}