368 lines
13 KiB
C#
368 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using SGModule.Common;
|
|
using SGModule.Common.Base;
|
|
using SGModule.Common.Helper;
|
|
using UnityEngine;
|
|
|
|
public class GMTool : SingletonMonoBehaviour<GMTool> {
|
|
private readonly int buttonHeight = 50;
|
|
private readonly int fontSize = 35; // 字体大小
|
|
|
|
private readonly Dictionary<string, string> inputFields = new();
|
|
|
|
private readonly List<GMToolItem> items = new();
|
|
private readonly int spacing = 10; // 控件之间的间距
|
|
private GUIStyle buttonStyle;
|
|
private int currentX; // 当前 X 坐标
|
|
private int currentY; // 当前 Y 坐标
|
|
private GUIStyle inputFieldStyle;
|
|
private GUIStyle labelStyle;
|
|
|
|
private bool toggleDisplay; // 控制显示与隐藏
|
|
private int windowWidth; // 屏幕宽度
|
|
|
|
|
|
protected override void Awake() {
|
|
base.Awake();
|
|
if (!ConfigManager.GameConfig.isRelease) {
|
|
IsInitComplete = true;
|
|
}
|
|
}
|
|
|
|
private void OnGUI() {
|
|
if (!IsInitComplete) {
|
|
return;
|
|
}
|
|
|
|
// 初始化样式
|
|
if (buttonStyle == null || labelStyle == null || inputFieldStyle == null) {
|
|
InitializeStyles();
|
|
}
|
|
|
|
// 初始化布局
|
|
StartLayout();
|
|
|
|
// 显示开关按钮
|
|
AddButton(toggleDisplay ? "关闭 GM 工具" : "打开 GM 工具", () => {
|
|
toggleDisplay = !toggleDisplay;
|
|
});
|
|
|
|
if (!toggleDisplay) {
|
|
return;
|
|
}
|
|
|
|
|
|
// 添加控件示例
|
|
AddLabel("GM 工具");
|
|
// AddButton("初始化网络模块", () =>
|
|
// {
|
|
// var gameConfig = ConfigManager.GetInstance.GetGameConfig();
|
|
// NetworkKit.Instance.InitData(gameConfig.packageName, gameConfig.isRelease);
|
|
// });
|
|
// AddButton("登录", () =>
|
|
// {
|
|
// NetworkKit.Instance.LoginRequest("Test", false, (arg0, model) =>
|
|
// {
|
|
// Debug.LogError($"登录结果 {arg0}");
|
|
// });
|
|
// });
|
|
|
|
|
|
// AddButton($"加载配置模块初始化", () =>
|
|
// {
|
|
// ConfigLoader.Instance.Init(NetworkKit.Instance.GetLoginModel().setting,
|
|
// NetworkKit.Instance.GetLoginModel().cdn_url, new List<ConfigModel>()
|
|
// {
|
|
// new CommonModel("Common"),
|
|
// new PrizeWheelDataModel("PrizeWheelData"),
|
|
// },
|
|
// state =>
|
|
// {
|
|
// Debug.LogError($"配置加载状态{state}");
|
|
// },
|
|
// (errorName, message) =>
|
|
// {
|
|
// Debug.LogError($"配置解析错误 {errorName} 错误信息:{message}");
|
|
// }
|
|
// );
|
|
// });
|
|
// AddButton($"读取Common配置", () =>
|
|
// {
|
|
// var model = ConfigLoader.Instance.GetConfig<CommonModel>();
|
|
// Debug.LogError(model);
|
|
// });
|
|
// AddButton($"读取PrizeWheelDataModel配置", () =>
|
|
// {
|
|
// var model = ConfigLoader.Instance.GetConfig<PrizeWheelDataModel>();
|
|
// Debug.LogError(model.DataList.Count);
|
|
// });
|
|
// AddButton($"测试解析为自定义配置", () =>
|
|
// {
|
|
// Debug.LogError(ConfigLoader.Instance.ParesPersonalizedConfig(new PrizeWheelDataModel("PrizeWheelData"), "prize"));
|
|
// });
|
|
// AddButton($"读取自定义配置", () =>
|
|
// {
|
|
// var personalizedConfig = ConfigLoader.Instance.GetPersonalizedConfig<PrizeWheelDataModel>("prize");
|
|
// Debug.LogError(personalizedConfig.DataList.Count);
|
|
// });
|
|
|
|
|
|
UpdateItems();
|
|
|
|
|
|
// AddButton("退出游戏", Application.Quit);
|
|
}
|
|
|
|
private void InitializeStyles() {
|
|
buttonStyle = new GUIStyle(GUI.skin.button) {
|
|
fontSize = fontSize,
|
|
alignment = TextAnchor.MiddleCenter,
|
|
normal = { textColor = Color.green }
|
|
};
|
|
|
|
labelStyle = new GUIStyle(GUI.skin.label) {
|
|
fontSize = fontSize,
|
|
normal = { textColor = Color.red }
|
|
};
|
|
|
|
inputFieldStyle = new GUIStyle(GUI.skin.textField) {
|
|
fontSize = fontSize,
|
|
alignment = TextAnchor.MiddleLeft
|
|
};
|
|
}
|
|
|
|
private void StartLayout() {
|
|
currentX = spacing;
|
|
currentY = spacing;
|
|
windowWidth = Screen.width;
|
|
}
|
|
|
|
private void AddButton(string text, Action onClick) {
|
|
// 计算按钮宽度,基于标题内容自适应
|
|
var buttonWidth = Mathf.Max(150, Mathf.CeilToInt(buttonStyle.CalcSize(new GUIContent(text)).x) + 20);
|
|
|
|
// 换行检查
|
|
if (currentX + buttonWidth + spacing > windowWidth) {
|
|
currentX = spacing;
|
|
currentY += buttonHeight + spacing;
|
|
}
|
|
|
|
// 绘制按钮
|
|
if (GUI.Button(new Rect(currentX, currentY, buttonWidth, buttonHeight), text, buttonStyle)) {
|
|
onClick?.Invoke();
|
|
}
|
|
|
|
// 更新下一个控件的位置
|
|
currentX += buttonWidth + spacing;
|
|
}
|
|
|
|
private void AddLabel(string text) {
|
|
// // 计算标签宽度和高度
|
|
// Vector2 size = labelStyle.CalcSize(new GUIContent(text));
|
|
// int labelWidth = Mathf.CeilToInt(size.x);
|
|
// int labelHeight = Mathf.CeilToInt(size.y);
|
|
//
|
|
// // 换行检查
|
|
// if (currentX + labelWidth + spacing > windowWidth)
|
|
// {
|
|
// currentX = spacing;
|
|
// currentY += buttonHeight + spacing;
|
|
// }
|
|
//
|
|
// // 绘制标签
|
|
// GUI.Label(new Rect(currentX, currentY, labelWidth, labelHeight), text, labelStyle);
|
|
//
|
|
// // 更新下一个控件的位置
|
|
// currentX += labelWidth + spacing;
|
|
|
|
// 启用自动换行 可用
|
|
labelStyle.wordWrap = true;
|
|
|
|
var size = labelStyle.CalcSize(new GUIContent(text));
|
|
var labelWidth = Mathf.CeilToInt(size.x);
|
|
var labelHeight = Mathf.CeilToInt(size.y);
|
|
|
|
// 计算标签宽度和高度
|
|
var maxWidth = windowWidth - spacing * 2; // 标签最大宽度
|
|
// float labelWidth = maxWidth; // 长文本直接占满一行
|
|
var needNewRow = labelWidth / maxWidth > 0.6f;
|
|
if (needNewRow) {
|
|
labelWidth = maxWidth;
|
|
labelHeight = (int) labelStyle.CalcHeight(new GUIContent(text), labelWidth);
|
|
}
|
|
|
|
// 换行逻辑:如果当前行剩余宽度不足,提前换行
|
|
if (currentX + labelWidth + spacing > windowWidth) {
|
|
currentX = spacing; // 回到左侧
|
|
currentY += buttonHeight + spacing; // 换到下一行
|
|
}
|
|
|
|
// 绘制标签
|
|
GUI.Label(new Rect(currentX, currentY, labelWidth, labelHeight), text, labelStyle);
|
|
|
|
// 更新位置:占满一整行,因此重置到新行
|
|
if (needNewRow) {
|
|
currentX = spacing;
|
|
currentY += labelHeight + spacing;
|
|
}
|
|
else {
|
|
currentX += labelWidth + spacing;
|
|
}
|
|
}
|
|
|
|
private void AddInputField(string key, string placeholder, string buttonText, Action<string> onSubmit) {
|
|
var inputFieldWidth = Mathf.Max(200, Mathf.CeilToInt(inputFieldStyle.CalcSize(new GUIContent(placeholder)).x) + 20);
|
|
var buttonWidth = Mathf.Max(100, Mathf.CeilToInt(buttonStyle.CalcSize(new GUIContent(buttonText)).x) + 20);
|
|
|
|
if (currentX + inputFieldWidth + buttonWidth + spacing * 2 > windowWidth) {
|
|
currentX = spacing;
|
|
currentY += buttonHeight + spacing;
|
|
}
|
|
|
|
if (!inputFields.TryGetValue(key, out var inputField)) {
|
|
inputFields.Add(key, "");
|
|
}
|
|
|
|
|
|
inputField = GUI.TextField(new Rect(currentX, currentY, inputFieldWidth, buttonHeight), inputField, inputFieldStyle);
|
|
currentX += inputFieldWidth + spacing;
|
|
|
|
if (GUI.Button(new Rect(currentX, currentY, buttonWidth, buttonHeight), buttonText, buttonStyle)) {
|
|
onSubmit?.Invoke(inputField);
|
|
}
|
|
|
|
inputFields[key] = inputField;
|
|
|
|
currentX += buttonWidth + spacing;
|
|
}
|
|
|
|
private void AddSeparator(string text = "") {
|
|
// 换行以确保分割线占据整行
|
|
currentX = spacing;
|
|
currentY += buttonHeight + spacing;
|
|
|
|
// // 分割线高度和宽度
|
|
// int separatorHeight = Mathf.CeilToInt(fontSize * 1.5f); // 动态设置高度
|
|
// int separatorWidth = windowWidth - spacing * 2;
|
|
//
|
|
// // 计算文字尺寸
|
|
// Vector2 textSize = labelStyle.CalcSize(new GUIContent(text));
|
|
// int textWidth = Mathf.CeilToInt(textSize.x);
|
|
//
|
|
// // 绘制分割线
|
|
// Rect lineRect = new Rect(currentX, currentY + separatorHeight / 2, separatorWidth, 1);
|
|
// GUI.Box(lineRect, GUIContent.none);
|
|
//
|
|
//
|
|
// // 绘制文字
|
|
// if (!string.IsNullOrEmpty(text))
|
|
// {
|
|
// GUI.Label(new Rect((windowWidth - textWidth) / 2, currentY, textWidth, separatorHeight), text, labelStyle);
|
|
// }
|
|
|
|
// 分割线宽度和高度
|
|
var separatorWidth = windowWidth - spacing * 2;
|
|
var separatorHeight = Mathf.CeilToInt(fontSize * 1.5f); // 分割线高度(文字高度)
|
|
var lineHeight = Mathf.CeilToInt(fontSize * 0.1f); // 线条高度
|
|
|
|
if (string.IsNullOrEmpty(text)) {
|
|
// 如果没有文字,绘制整行分割线
|
|
DrawLine(new Rect(currentX, currentY + separatorHeight / 2 - lineHeight / 2, separatorWidth, lineHeight));
|
|
}
|
|
else {
|
|
// 计算文字尺寸
|
|
var textSize = labelStyle.CalcSize(new GUIContent(text));
|
|
var textWidth = Mathf.CeilToInt(textSize.x);
|
|
|
|
// 计算分割线两侧长度
|
|
var lineWidth = (separatorWidth - textWidth - spacing * 2) / 2;
|
|
|
|
// 绘制左侧线条
|
|
DrawLine(new Rect(currentX, currentY + separatorHeight / 2 - lineHeight / 2, lineWidth, lineHeight));
|
|
|
|
// 绘制文字
|
|
GUI.Label(new Rect(currentX + lineWidth + spacing, currentY, textWidth, separatorHeight), text, labelStyle);
|
|
|
|
// 绘制右侧线条
|
|
DrawLine(new Rect(currentX + lineWidth + textWidth + spacing * 2, currentY + separatorHeight / 2 - lineHeight / 2, lineWidth,
|
|
lineHeight));
|
|
}
|
|
|
|
// 更新位置
|
|
currentY += separatorHeight + spacing;
|
|
}
|
|
|
|
private void DrawLine(Rect rect) {
|
|
// 设置线条颜色
|
|
var originalColor = GUI.color;
|
|
GUI.color = Color.white; // 可以改成其他颜色
|
|
|
|
// 绘制线条
|
|
GUI.DrawTexture(rect, Texture2D.whiteTexture);
|
|
|
|
// 恢复原始颜色
|
|
GUI.color = originalColor;
|
|
}
|
|
|
|
public void AddItem(GMToolItem item) {
|
|
items.Add(item);
|
|
}
|
|
|
|
private void UpdateItems() {
|
|
foreach (var item in items) {
|
|
switch (item.Type) {
|
|
case GUIType.Label:
|
|
AddLabel(item.TextFunc.Invoke());
|
|
break;
|
|
case GUIType.Button:
|
|
AddButton(item.TextFunc.Invoke(), () => {
|
|
item.OnClick?.Invoke(null);
|
|
});
|
|
break;
|
|
case GUIType.InputField:
|
|
AddInputField(item.Key, item.Placeholder, item.TextFunc.Invoke(), s => {
|
|
item.OnClick?.Invoke(s);
|
|
});
|
|
break;
|
|
case GUIType.Separator:
|
|
AddSeparator(item.TextFunc?.Invoke());
|
|
break;
|
|
default:
|
|
Log.Common.Error($"Unsupported GUIType: {item.Type}");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum GUIType {
|
|
Label,
|
|
Button,
|
|
InputField,
|
|
Separator // 分割线类型
|
|
}
|
|
|
|
public class GMToolItem {
|
|
public string Key;
|
|
public Action<string> OnClick;
|
|
public string Placeholder;
|
|
public Func<string> TextFunc;
|
|
public GUIType Type;
|
|
|
|
/// <summary>
|
|
/// </summary>
|
|
/// <param name="type">控件类型</param>
|
|
/// <param name="textFunc">显示的文本,传入委托可以动态变化</param>
|
|
/// <param name="onClick">点击委托,只有Button与InputField有效,Button可忽略字符串参数,InputField输入的内容会传入</param>
|
|
/// <param name="key">InputField 需要用到的key,记得保持唯一性,如果重复有可能会导致重复的输入框同步一样的内容</param>
|
|
/// <param name="placeholder">提示占位文本</param>
|
|
public GMToolItem(GUIType type, Func<string> textFunc, Action<string> onClick = null, string key = "", string placeholder = "") {
|
|
Type = type;
|
|
TextFunc = textFunc;
|
|
OnClick = onClick;
|
|
Key = key;
|
|
Placeholder = placeholder;
|
|
}
|
|
}
|