245 lines
11 KiB
C#
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);
|
|
}
|
|
}
|