using UnityEngine; using UnityEngine.UI; using UnityEditor; using TMPro; public class MainMenuSkeletonBuilder : EditorWindow { [MenuItem("Tools/Build Main Menu Skeleton")] public static void Build() { // ---------- CANVAS ---------- GameObject canvasGO = new GameObject("MainMenu_Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster)); Canvas canvas = canvasGO.GetComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; CanvasScaler scaler = canvasGO.GetComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1080, 1920); scaler.matchWidthOrHeight = 0.5f; if (Object.FindAnyObjectByType() == null) { new GameObject("EventSystem", typeof(UnityEngine.EventSystems.EventSystem), typeof(UnityEngine.EventSystems.StandaloneInputModule)); } RectTransform canvasRect = canvasGO.GetComponent(); // ---------- ФОН ---------- RectTransform background = CreatePanel(canvasRect, "Background", new Color(0.12f, 0.15f, 0.13f)); AnchorFillWithOffset(background, Vector4.zero); // Лёгкое затемнение снизу, чтобы кнопки читались на любом фоне (частый приём в таких меню) RectTransform bottomShade = CreatePanel(canvasRect, "BottomShade", new Color(0f, 0f, 0f, 0.35f)); AnchorBottomStretch(bottomShade, height: 900); // ---------- ЛОГОТИП / НАЗВАНИЕ ---------- RectTransform logoBG = CreatePanel(canvasRect, "LogoPlaceholder", new Color(0.2f, 0.18f, 0.12f, 0.9f)); AnchorTopCenter(logoBG, new Vector2(700, 220), new Vector2(0, -180)); CreateText(logoBG, "TitleText", "НАЗВАНИЕ ИГРЫ", 42); // ---------- КНОПКИ (вертикальный стек, снизу) ---------- string[] buttonNames = { "PlayButton", "SettingsButton", "ExitButton" }; string[] buttonLabels = { "ИГРАТЬ", "НАСТРОЙКИ", "ВЫХОД" }; Color[] buttonColors = { new Color(0.15f, 0.45f, 0.2f), // играть -- выделенная, самая заметная new Color(0.2f, 0.2f, 0.22f), // настройки -- нейтральная new Color(0.35f, 0.15f, 0.15f) // выход -- приглушённо-тревожная }; float[] buttonHeights = { 140, 110, 110 }; float currentY = 480; // отступ снизу для первой (нижней) кнопки // Идём снизу вверх: Выход внизу всего, Играть -- выше всех (частый паттерн: главное действие ближе к центру) for (int i = buttonNames.Length - 1; i >= 0; i--) { RectTransform btn = CreateButton(canvasRect, buttonNames[i], buttonLabels[i], buttonColors[i]); AnchorBottomCenter(btn, new Vector2(650, buttonHeights[i]), new Vector2(0, currentY)); GetText(btn).fontSize = (buttonNames[i] == "PlayButton") ? 36 : 26; currentY += buttonHeights[i] + 30; } // ---------- ВЕРСИЯ ИГРЫ (мелкий текст в углу, обычно нужен для отладки/поддержки) ---------- RectTransform versionText = CreateText(canvasRect, "VersionLabel", "v0.0.1", 18); AnchorBottomRightSmall(versionText); Selection.activeGameObject = canvasGO; Debug.Log("Скелет главного меню создан: Background, LogoPlaceholder, PlayButton, SettingsButton, ExitButton."); } // ---------------- HELPERS ---------------- static RectTransform CreatePanel(RectTransform parent, string name, Color color) { GameObject go = new GameObject(name, typeof(RectTransform), typeof(Image)); go.transform.SetParent(parent, false); go.GetComponent().color = color; return go.GetComponent(); } static RectTransform CreateText(RectTransform parent, string name, string content, int fontSize) { GameObject go = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI)); go.transform.SetParent(parent, false); TextMeshProUGUI tmp = go.GetComponent(); tmp.text = content; tmp.fontSize = fontSize; tmp.color = Color.white; tmp.alignment = TextAlignmentOptions.Center; RectTransform rt = go.GetComponent(); rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 1); rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero; return rt; } static TextMeshProUGUI GetText(RectTransform parent) { return parent.GetComponentInChildren(); } static RectTransform CreateButton(RectTransform parent, string name, string label, Color color) { GameObject go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button)); go.transform.SetParent(parent, false); go.GetComponent().color = color; RectTransform rt = go.GetComponent(); CreateText(rt, "Label", label, 28); return rt; } static void AnchorFillWithOffset(RectTransform rt, Vector4 leftTopRightBottom) { rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 1); rt.offsetMin = new Vector2(leftTopRightBottom.x, leftTopRightBottom.w); rt.offsetMax = new Vector2(-leftTopRightBottom.z, -leftTopRightBottom.y); } static void AnchorBottomStretch(RectTransform rt, float height) { rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 0); rt.pivot = new Vector2(0.5f, 0); rt.sizeDelta = new Vector2(0, height); rt.anchoredPosition = Vector2.zero; } static void AnchorTopCenter(RectTransform rt, Vector2 size, Vector2 pos) { rt.anchorMin = new Vector2(0.5f, 1); rt.anchorMax = new Vector2(0.5f, 1); rt.pivot = new Vector2(0.5f, 1); rt.sizeDelta = size; rt.anchoredPosition = pos; } static void AnchorBottomCenter(RectTransform rt, Vector2 size, Vector2 pos) { rt.anchorMin = new Vector2(0.5f, 0); rt.anchorMax = new Vector2(0.5f, 0); rt.pivot = new Vector2(0.5f, 0); rt.sizeDelta = size; rt.anchoredPosition = pos; } static void AnchorBottomRightSmall(RectTransform rt) { rt.anchorMin = new Vector2(1, 0); rt.anchorMax = new Vector2(1, 0); rt.pivot = new Vector2(1, 0); rt.sizeDelta = new Vector2(150, 40); rt.anchoredPosition = new Vector2(-20, 20); } }