Files
MVP1/Assets/Editor/HUDSkeletonBuilder.cs
T

245 lines
11 KiB
C#

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>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
CanvasScaler scaler = canvasGO.GetComponent<CanvasScaler>();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(1080, 1920); // стандартное портретное разрешение
scaler.matchWidthOrHeight = 0.5f;
if (Object.FindAnyObjectByType<UnityEngine.EventSystems.EventSystem>() == null)
{
GameObject es = new GameObject("EventSystem",
typeof(UnityEngine.EventSystems.EventSystem),
typeof(UnityEngine.EventSystems.StandaloneInputModule));
}
RectTransform canvasRect = canvasGO.GetComponent<RectTransform>();
// ---------- ВЕРХНЯЯ ПАНЕЛЬ ----------
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<Image>().color = color;
return go.GetComponent<RectTransform>();
}
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<TextMeshProUGUI>();
tmp.text = content;
tmp.fontSize = fontSize;
tmp.color = Color.white;
tmp.alignment = TextAlignmentOptions.Center;
RectTransform rt = go.GetComponent<RectTransform>();
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<Image>().color = color;
RectTransform rt = go.GetComponent<RectTransform>();
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<Image>().color = new Color(0.75f, 0.15f, 0.15f);
RectTransform rt = go.GetComponent<RectTransform>();
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);
}
}