using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.UI; using TMPro; using BaseGames.UI.MainMenu; using BaseGames.UI.Theme; using BaseGames.Core.Events; using BaseGames.Localization; using BaseGames.Editor.Localization; namespace BaseGames.Editor.UI { /// /// 新游戏难度选择脚手架:生成 / 更新 UI_NewGameModePanel 预制件 + 默认 UI_NewGameModeConfig 表 + 中英文案。 /// 该面板是 MainMenu Canvas 的子面板(非独立 Canvas),由 SaveSlotController 经 ShowAsync 模态弹出。 /// /// 美术 → 改 UI_NewGameModePanel 预制件(暗化/对话框/标题/说明/返回样式,难度按钮样式见 UI_MainMenu_Button); /// 策划 → 改 UI_NewGameModeConfig(增删/重排难度、改标签/说明)。 /// /// 菜单:BaseGames/UI/控件库/生成新游戏难度选择(预制件 + 默认配置) /// public static class UINewGameModeScaffold { private const string PrefabDir = "Assets/_Game/Prefabs/UI"; private const string ConfigDir = "Assets/_Game/Data/UI"; private const string ThemePath = "Assets/_Game/Data/UI/Themes/UI_Theme_Default.asset"; private const string PrefabName = "UI_NewGameModePanel"; private const string ConfigName = "UI_NewGameModeConfig"; private const string BtnPrefabPath = "Assets/_Game/Prefabs/UI/Controls/UI_MainMenu_Button.prefab"; [MenuItem("BaseGames/UI/控件库/生成新游戏难度选择(预制件 + 默认配置)")] public static void GeneratePrefab() { EnsureFolder(PrefabDir); EnsureFolder(ConfigDir); var report = new List(); var theme = AssetDatabase.LoadAssetAtPath(ThemePath); var config = EnsureDefaultConfig(report); SeedLocalization(report); BuildPrefab(theme, config, report); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); var sb = new System.Text.StringBuilder("[UINewGameMode] 难度选择已生成/更新:\n"); foreach (var r in report) sb.AppendLine(" • " + r); sb.AppendLine("用法:重跑「BaseGames/Scene/Setup/Scaffold MainMenu Scene」实例化进 MainMenu(接 SaveSlotController._modeSelect)。"); Debug.Log(sb.ToString()); } private static void BuildPrefab(UIThemeSO theme, NewGameModeConfigSO config, List report) { // 根:铺满全屏的面板(非 Canvas;作为 MainMenu Canvas 子节点)。初始隐藏,由导航器激活。 var root = new GameObject(PrefabName, typeof(RectTransform), typeof(CanvasGroup)); var rootRt = (RectTransform)root.transform; Stretch(rootRt); var ctrl = root.AddComponent(); var applier = root.AddComponent(); if (theme != null) AssignRef(applier, "_theme", theme); // 暗化遮罩(铺满,挡点击) var overlayGo = NewUIChild(root.transform, "Overlay", out var overlayRt); Stretch(overlayRt); var overlay = overlayGo.AddComponent(); overlay.color = new Color(0f, 0f, 0f, 0.6f); overlay.raycastTarget = true; // 对话框 var boxGo = NewUIChild(root.transform, "DialogBox", out var boxRt); SetRect(boxRt, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(760f, 520f)); var box = boxGo.AddComponent(); box.sprite = Standard(); box.type = Image.Type.Sliced; box.color = new Color(0.10f, 0.11f, 0.15f, 0.98f); SetEnum(boxGo.AddComponent(), "_kind", (int)UIThemeRoleKind.Graphic_Background); // 标题 var titleGo = NewUIChild(boxGo.transform, "Title", out var titleRt); SetRect(titleRt, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -50f), new Vector2(-60f, 60f)); var title = titleGo.AddComponent(); title.text = "选择难度"; title.alignment = TextAlignmentOptions.Center; title.fontSize = 40f; title.raycastTarget = false; var titleLoc = titleGo.AddComponent(); SetString(titleLoc, "_key", "MODE_SELECT_TITLE"); SetEnum(titleGo.AddComponent(), "_kind", (int)UIThemeRoleKind.Text_Header); // 难度按钮容器(竖排) var optionGo = NewUIChild(boxGo.transform, "OptionContainer", out var optionRt); SetRect(optionRt, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -130f), new Vector2(460f, 200f)); var vlg = optionGo.AddComponent(); vlg.spacing = 12f; vlg.childAlignment = TextAnchor.UpperCenter; vlg.childControlWidth = true; vlg.childControlHeight = true; vlg.childForceExpandWidth = true; vlg.childForceExpandHeight = false; // 说明文本(选中项时显示) var descGo = NewUIChild(boxGo.transform, "DescText", out var descRt); SetRect(descRt, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 130f), new Vector2(-80f, 80f)); var desc = descGo.AddComponent(); desc.text = ""; desc.alignment = TextAlignmentOptions.Center; desc.fontSize = 22f; desc.color = new Color(0.82f, 0.6f, 0.6f, 1f); desc.raycastTarget = false; desc.enableWordWrapping = true; SetEnum(descGo.AddComponent(), "_kind", (int)UIThemeRoleKind.Text_Secondary); // 返回按钮 var backGo = NewUIChild(boxGo.transform, "Btn_Back", out var backRt); SetRect(backRt, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 46f), new Vector2(260f, 60f)); var backImg = backGo.AddComponent(); backImg.sprite = Standard(); backImg.type = Image.Type.Sliced; backImg.color = new Color(1f, 1f, 1f, 0.06f); var backBtn = backGo.AddComponent