using UnityEngine; using UnityEngine.UI; using UnityEditor; using TMPro; public class HUDSkeletonBuilder : EditorWindow { [MenuItem("Tools/Build HUD Skeleton")] public static void Build() { // ---------- CANVAS ---------- GameObject canvasGO = new GameObject("HUD_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) { GameObject es = new GameObject("EventSystem", typeof(UnityEngine.EventSystems.EventSystem), typeof(UnityEngine.EventSystems.StandaloneInputModule)); } RectTransform canvasRect = canvasGO.GetComponent(); // ---------- ВЕРХНЯЯ ПАНЕЛЬ ---------- RectTransform topBar = CreatePanel(canvasRect, "TopBar", new Color(0.08f, 0.08f, 0.1f, 0.85f)); AnchorTopStretch(topBar, height: 140, topOffset: 0); // Аватар + уровень (слева) RectTransform avatarBG = CreateImage(topBar, "PlayerAvatar", new Color(0.3f, 0.3f, 0.35f)); AnchorTopLeft(avatarBG, new Vector2(110, 110), new Vector2(20, -15)); CreateBadge(avatarBG, "LevelBadge", "24", new Vector2(-8, -8)); // Ресурсы (горизонтальный ряд по центру-верху) string[] resourceNames = { "Power", "Food", "Wood", "Gold", "Gems" }; string[] resourcePlaceholders = { "812,430", "1.2M", "2.4M", "756K", "128K" }; Color[] resourceColors = { new Color(0.6f, 0.5f, 0.1f), new Color(0.6f, 0.2f, 0.2f), new Color(0.4f, 0.3f, 0.15f), new Color(0.7f, 0.6f, 0.15f), new Color(0.15f, 0.5f, 0.7f) }; float resourceStartX = 150; float resourceWidth = 180; for (int i = 0; i < resourceNames.Length; i++) { RectTransform pill = CreatePanel(topBar, "Resource_" + resourceNames[i], new Color(0.15f, 0.15f, 0.18f, 0.9f)); AnchorTopLeft(pill, new Vector2(resourceWidth, 60), new Vector2(resourceStartX + i * (resourceWidth + 10), -20)); RectTransform icon = CreateImage(pill, "Icon", resourceColors[i]); AnchorLeftMiddle(icon, new Vector2(40, 40), new Vector2(10, 0)); RectTransform text = CreateText(pill, "Value", resourcePlaceholders[i], 24); AnchorFillWithOffset(text, new Vector4(58, 0, 40, 0)); RectTransform plusBtn = CreateButton(pill, "PlusButton", "+", new Color(0.2f, 0.6f, 0.25f)); AnchorRightMiddle(plusBtn, new Vector2(30, 30), new Vector2(-8, 0)); } // Настройки (справа) RectTransform settingsBtn = CreateButton(topBar, "SettingsButton", "\u2699", new Color(0.25f, 0.25f, 0.28f)); AnchorTopRight(settingsBtn, new Vector2(70, 70), new Vector2(-20, -15)); // ---------- ЛЕВАЯ КОЛОНКА ---------- string[] leftButtons = { "Quests", "Mail" }; string[] leftLabels = { "ЗАДАНИЯ", "ПОЧТА" }; string[] leftBadges = { "2", "1" }; for (int i = 0; i < leftButtons.Length; i++) { RectTransform btn = CreatePanel(canvasRect, "LeftBtn_" + leftButtons[i], new Color(0.15f, 0.13f, 0.1f, 0.9f)); AnchorTopLeft(btn, new Vector2(150, 150), new Vector2(20, -220 - i * 170)); CreateText(btn, "Label", leftLabels[i], 22).anchoredPosition = new Vector2(0, -55); CreateBadge(btn, "CountBadge", leftBadges[i], new Vector2(8, -8)); } // ---------- ПРАВАЯ КОЛОНКА ---------- string[] rightButtons = { "Events", "Rewards" }; string[] rightLabels = { "СОБЫТИЯ", "НАГРАДЫ" }; string[] rightBadges = { "3", "1" }; for (int i = 0; i < rightButtons.Length; i++) { RectTransform btn = CreatePanel(canvasRect, "RightBtn_" + rightButtons[i], new Color(0.15f, 0.13f, 0.1f, 0.9f)); AnchorTopRight(btn, new Vector2(150, 150), new Vector2(-20, -220 - i * 170)); CreateText(btn, "Label", rightLabels[i], 22).anchoredPosition = new Vector2(0, -55); CreateBadge(btn, "CountBadge", rightBadges[i], new Vector2(-8, -8)); } // ---------- НИЖНЯЯ НАВИГАЦИЯ ---------- RectTransform bottomBar = CreatePanel(canvasRect, "BottomNavBar", new Color(0.08f, 0.08f, 0.1f, 0.92f)); AnchorBottomStretch(bottomBar, height: 190); string[] navNames = { "Home", "Hero", "Battle", "Troops", "Shop", "ARENA" }; string[] navLabels = { "ГЛАВНАЯ", "ГЕРОЙ", "БОЙ", "ВОЙСКА", "МАГАЗИН", "АРЕНА" }; float navWidth = 1080f / 5f; for (int i = 0; i < navNames.Length; i++) { bool isCenter = navNames[i] == "Battle"; RectTransform navBtn = CreatePanel(bottomBar, "Nav_" + navNames[i], isCenter ? new Color(0.12f, 0.3f, 0.55f, 1f) : new Color(0.15f, 0.15f, 0.18f, 0f)); AnchorTopLeft(navBtn, new Vector2(navWidth, 190), new Vector2(i * navWidth, 0)); RectTransform icon = CreateImage(navBtn, "Icon", isCenter ? new Color(0.7f, 0.75f, 0.8f) : new Color(0.4f, 0.4f, 0.42f)); icon.anchorMin = new Vector2(0.5f, 0.55f); icon.anchorMax = new Vector2(0.5f, 0.55f); icon.sizeDelta = isCenter ? new Vector2(90, 90) : new Vector2(60, 60); icon.anchoredPosition = Vector2.zero; RectTransform label = CreateText(navBtn, "Label", navLabels[i], isCenter ? 26 : 20); label.anchorMin = new Vector2(0.5f, 0f); label.anchorMax = new Vector2(0.5f, 0f); label.pivot = new Vector2(0.5f, 0f); label.sizeDelta = new Vector2(navWidth - 10, 40); label.anchoredPosition = new Vector2(0, 20); } Selection.activeGameObject = canvasGO; Debug.Log("HUD-скелет создан. Все объекты названы по функции -- дизайнеры меняют Image/Sprite на месте, структуру не трогают."); } // ---------------- 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 CreateImage(RectTransform parent, string name, Color color) { return CreatePanel(parent, name, color); } 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 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 CreateBadge(RectTransform parent, string name, string count, Vector2 cornerOffset) { GameObject go = new GameObject(name, typeof(RectTransform), typeof(Image)); go.transform.SetParent(parent, false); go.GetComponent().color = new Color(0.75f, 0.15f, 0.15f); RectTransform rt = go.GetComponent(); rt.anchorMin = new Vector2(1, 1); rt.anchorMax = new Vector2(1, 1); rt.pivot = new Vector2(1, 1); rt.sizeDelta = new Vector2(36, 36); rt.anchoredPosition = cornerOffset; CreateText(rt, "Count", count, 20); } // ---- Anchor helpers (упрощают позиционирование под мобильный экран) ---- static void AnchorTopStretch(RectTransform rt, float height, float topOffset) { rt.anchorMin = new Vector2(0, 1); rt.anchorMax = new Vector2(1, 1); rt.pivot = new Vector2(0.5f, 1); rt.sizeDelta = new Vector2(0, height); rt.anchoredPosition = new Vector2(0, -topOffset); } 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 AnchorTopLeft(RectTransform rt, Vector2 size, Vector2 pos) { rt.anchorMin = new Vector2(0, 1); rt.anchorMax = new Vector2(0, 1); rt.pivot = new Vector2(0, 1); rt.sizeDelta = size; rt.anchoredPosition = pos; } static void AnchorTopRight(RectTransform rt, Vector2 size, Vector2 pos) { rt.anchorMin = new Vector2(1, 1); rt.anchorMax = new Vector2(1, 1); rt.pivot = new Vector2(1, 1); rt.sizeDelta = size; rt.anchoredPosition = pos; } static void AnchorLeftMiddle(RectTransform rt, Vector2 size, Vector2 pos) { rt.anchorMin = new Vector2(0, 0.5f); rt.anchorMax = new Vector2(0, 0.5f); rt.pivot = new Vector2(0, 0.5f); rt.sizeDelta = size; rt.anchoredPosition = pos; } static void AnchorRightMiddle(RectTransform rt, Vector2 size, Vector2 pos) { rt.anchorMin = new Vector2(1, 0.5f); rt.anchorMax = new Vector2(1, 0.5f); rt.pivot = new Vector2(1, 0.5f); rt.sizeDelta = size; rt.anchoredPosition = pos; } 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); } }