2026-10-12 23:54:03 +03:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using TMPro;
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
using UnityEditor.SceneManagement;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
|
|
// Tools -> Build World Map Scene
|
|
|
|
|
|
// 1. Создаёт сцену Assets/Scenes/WorldMap.unity: камера, EventSystem, UI карты, WorldMapController.
|
|
|
|
|
|
// 2. Ставит MVP1 и WorldMap в Build Settings (иначе SceneManager.LoadScene их не найдёт).
|
|
|
|
|
|
// 3. Проверяет, что на кнопке Nav_Battle в городе висит OpenBattleButton.
|
|
|
|
|
|
// Можно запускать повторно -- сцена карты пересоздаётся заново.
|
|
|
|
|
|
public static class WorldMapSceneBuilder
|
|
|
|
|
|
{
|
|
|
|
|
|
const string WorldMapScenePath = "Assets/Scenes/WorldMap.unity";
|
|
|
|
|
|
const string CityScenePath = "Assets/Scenes/MVP1.unity";
|
|
|
|
|
|
|
|
|
|
|
|
[MenuItem("Tools/Build World Map Scene")]
|
|
|
|
|
|
public static void Build()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) return;
|
|
|
|
|
|
|
|
|
|
|
|
CreateWorldMapScene();
|
|
|
|
|
|
UpdateBuildSettings();
|
|
|
|
|
|
HookUpCityBattleButton();
|
|
|
|
|
|
|
|
|
|
|
|
Debug.Log("[КАРТА] Сцена карты мира создана, кнопка БОЙ в городе подключена. Запускай MVP1 и жми БОЙ.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- СЦЕНА КАРТЫ ----------------
|
|
|
|
|
|
|
|
|
|
|
|
static void CreateWorldMapScene()
|
|
|
|
|
|
{
|
|
|
|
|
|
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
|
|
|
|
|
|
|
|
|
|
|
var camGO = new GameObject("Main Camera", typeof(Camera), typeof(MapCameraController));
|
|
|
|
|
|
camGO.tag = "MainCamera";
|
|
|
|
|
|
camGO.transform.position = new Vector3(0, 0, -10);
|
|
|
|
|
|
Camera cam = camGO.GetComponent<Camera>();
|
|
|
|
|
|
cam.orthographic = true;
|
|
|
|
|
|
cam.orthographicSize = 8f;
|
|
|
|
|
|
cam.clearFlags = CameraClearFlags.SolidColor;
|
|
|
|
|
|
cam.backgroundColor = new Color(0.12f, 0.16f, 0.12f);
|
|
|
|
|
|
|
|
|
|
|
|
new GameObject("EventSystem", typeof(EventSystem), typeof(StandaloneInputModule));
|
|
|
|
|
|
|
|
|
|
|
|
var canvasGO = new GameObject("WorldMap_Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
|
|
|
|
|
canvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
|
|
|
|
|
CanvasScaler scaler = canvasGO.GetComponent<CanvasScaler>();
|
|
|
|
|
|
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
|
|
|
|
|
scaler.referenceResolution = new Vector2(1920, 1080);
|
|
|
|
|
|
scaler.matchWidthOrHeight = 0.5f;
|
|
|
|
|
|
RectTransform canvasRect = canvasGO.GetComponent<RectTransform>();
|
|
|
|
|
|
|
|
|
|
|
|
var controller = new GameObject("WorldMapController").AddComponent<WorldMapController>();
|
|
|
|
|
|
controller.mapCamera = camGO.GetComponent<MapCameraController>();
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Верхняя панель: назад | войско | мой город ----
|
|
|
|
|
|
RectTransform topBar = CreatePanel(canvasRect, "TopBar", new Color(0.08f, 0.08f, 0.1f, 0.85f));
|
|
|
|
|
|
AnchorStretch(topBar, top: true, height: 110);
|
|
|
|
|
|
|
|
|
|
|
|
controller.soldiersText = CreateText(topBar, "SoldiersText", "Войска дома: 30", 40);
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform back = CreateButton(topBar, "BackButton", "НАЗАД", new Color(0.3f, 0.3f, 0.33f), out _);
|
|
|
|
|
|
AnchorSide(back, left: true, new Vector2(220, 80), 20);
|
|
|
|
|
|
controller.backButton = back.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform myCity = CreateButton(topBar, "MyCityButton", "МОЙ ГОРОД", new Color(0.25f, 0.45f, 0.8f), out _);
|
|
|
|
|
|
AnchorSide(myCity, left: false, new Vector2(280, 80), 20);
|
|
|
|
|
|
controller.myCityButton = myCity.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Подсказка (над нижней панелью, правее чата) ----
|
|
|
|
|
|
RectTransform hintBar = CreatePanel(canvasRect, "HintBar", new Color(0.08f, 0.08f, 0.1f, 0.75f));
|
|
|
|
|
|
SetRect(hintBar, new Vector2(0, 0), new Vector2(1, 0), new Vector2(0.5f, 0), Vector2.zero, Vector2.zero);
|
|
|
|
|
|
hintBar.offsetMin = new Vector2(ChatWidth + 24, 172);
|
|
|
|
|
|
hintBar.offsetMax = new Vector2(-12, 222);
|
|
|
|
|
|
controller.hintText = CreateText(hintBar, "Hint", "", 28);
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Чат слева внизу ----
|
|
|
|
|
|
BuildChat(canvasRect);
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Нижняя панель: Карта мира | События | Круг | Поселение ----
|
|
|
|
|
|
BuildNavBar(canvasRect, controller);
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Кнопка "Рейтинг" слева ----
|
|
|
|
|
|
RectTransform ratingBtn = CreateButton(canvasRect, "RatingButton", "Рейтинг", new Color(0.12f, 0.2f, 0.4f, 0.95f), out _);
|
|
|
|
|
|
SetRect(ratingBtn, new Vector2(0, 1), new Vector2(0, 1), new Vector2(0, 1), new Vector2(12, -122), new Vector2(210, 110));
|
|
|
|
|
|
controller.ratingButton = ratingBtn.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Панель рейтинга (выше всего, кроме окна атаки и уведомлений) ----
|
|
|
|
|
|
controller.ratingPanel = BuildRatingPanel(canvasRect);
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Окно атаки ----
|
|
|
|
|
|
RectTransform attack = CreateCenterPanel(canvasRect, "AttackPanel", new Vector2(900, 640));
|
|
|
|
|
|
controller.attackPanel = attack.gameObject;
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform attackTitle = CreateTextRect(attack, "Title", "Замок", 56);
|
|
|
|
|
|
AnchorTop(attackTitle, 110, 20);
|
|
|
|
|
|
controller.attackTitleText = attackTitle.GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform attackInfo = CreateTextRect(attack, "Info", "", 32);
|
|
|
|
|
|
AnchorTop(attackInfo, 170, 130);
|
|
|
|
|
|
controller.attackInfoText = attackInfo.GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform sendCount = CreateTextRect(attack, "SoldiersToSend", "Отправить: 30 из 30", 36);
|
|
|
|
|
|
AnchorTop(sendCount, 60, 310);
|
|
|
|
|
|
controller.soldiersToSendText = sendCount.GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
GameObject sliderGO = DefaultControls.CreateSlider(new DefaultControls.Resources());
|
|
|
|
|
|
sliderGO.name = "SoldiersSlider";
|
|
|
|
|
|
RectTransform sliderRect = sliderGO.GetComponent<RectTransform>();
|
|
|
|
|
|
sliderRect.SetParent(attack, false);
|
|
|
|
|
|
AnchorTop(sliderRect, 50, 390);
|
|
|
|
|
|
sliderRect.offsetMin = new Vector2(80, sliderRect.offsetMin.y);
|
|
|
|
|
|
sliderRect.offsetMax = new Vector2(-80, sliderRect.offsetMax.y);
|
|
|
|
|
|
StyleSlider(sliderGO);
|
|
|
|
|
|
controller.soldiersSlider = sliderGO.GetComponent<Slider>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform send = CreateButton(attack, "SendButton", "В ПОХОД", new Color(0.75f, 0.25f, 0.15f), out _);
|
|
|
|
|
|
AnchorBottom(send, new Vector2(320, 100), new Vector2(170, 30));
|
|
|
|
|
|
controller.sendButton = send.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform cancel = CreateButton(attack, "CancelButton", "ОТМЕНА", new Color(0.3f, 0.3f, 0.33f), out _);
|
|
|
|
|
|
AnchorBottom(cancel, new Vector2(320, 100), new Vector2(-170, 30));
|
|
|
|
|
|
controller.cancelButton = cancel.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
attack.gameObject.SetActive(false);
|
|
|
|
|
|
|
|
|
|
|
|
// ---- Уведомление ----
|
|
|
|
|
|
RectTransform popup = CreateCenterPanel(canvasRect, "PopupPanel", new Vector2(860, 520));
|
|
|
|
|
|
controller.popupPanel = popup.gameObject;
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform popupTitle = CreateTextRect(popup, "Title", "ПОБЕДА", 72);
|
|
|
|
|
|
AnchorTop(popupTitle, 120, 20);
|
|
|
|
|
|
controller.popupTitleText = popupTitle.GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform popupBody = CreateTextRect(popup, "Body", "", 32);
|
|
|
|
|
|
popupBody.offsetMin = new Vector2(40, 140);
|
|
|
|
|
|
popupBody.offsetMax = new Vector2(-40, -140);
|
|
|
|
|
|
controller.popupBodyText = popupBody.GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform ok = CreateButton(popup, "OkButton", "OK", new Color(0.2f, 0.5f, 0.25f), out _);
|
|
|
|
|
|
AnchorBottom(ok, new Vector2(300, 100), new Vector2(0, 30));
|
|
|
|
|
|
controller.popupOkButton = ok.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
popup.gameObject.SetActive(false);
|
|
|
|
|
|
|
|
|
|
|
|
EditorSceneManager.SaveScene(scene, WorldMapScenePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- ЧАТ ----------------
|
|
|
|
|
|
|
|
|
|
|
|
const float ChatWidth = 620f;
|
|
|
|
|
|
|
|
|
|
|
|
static void BuildChat(RectTransform canvasRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform panel = CreatePanel(canvasRect, "ChatPanel", new Color(0.05f, 0.06f, 0.09f, 0.9f));
|
|
|
|
|
|
SetRect(panel, Vector2.zero, Vector2.zero, Vector2.zero, new Vector2(12, 12), new Vector2(ChatWidth, 350));
|
|
|
|
|
|
ChatPanel chat = panel.gameObject.AddComponent<ChatPanel>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform worldTab = CreateButton(panel, "WorldTab", "Общий мир", new Color(0.16f, 0.35f, 0.7f), out _);
|
|
|
|
|
|
SetRect(worldTab, new Vector2(0, 1), new Vector2(0, 1), new Vector2(0, 1), new Vector2(10, -10), new Vector2(220, 54));
|
|
|
|
|
|
chat.worldTabButton = worldTab.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform circleTab = CreateButton(panel, "CircleTab", "Круг", new Color(0.12f, 0.13f, 0.17f), out _);
|
|
|
|
|
|
SetRect(circleTab, new Vector2(0, 1), new Vector2(0, 1), new Vector2(0, 1), new Vector2(240, -10), new Vector2(220, 54));
|
|
|
|
|
|
chat.circleTabButton = circleTab.GetComponent<Button>();
|
|
|
|
|
|
|
2026-10-19 19:07:45 +02:00
|
|
|
|
RectTransform expand = CreateButton(panel, "ExpandButton", "Развернуть", new Color(0.12f, 0.13f, 0.17f), out TMP_Text expandText);
|
|
|
|
|
|
SetRect(expand, new Vector2(1, 1), new Vector2(1, 1), new Vector2(1, 1), new Vector2(-10, -10), new Vector2(150, 54));
|
|
|
|
|
|
expandText.fontSize = 24;
|
|
|
|
|
|
chat.expandButton = expand.GetComponent<Button>();
|
|
|
|
|
|
|
2026-10-12 23:54:03 +03:00
|
|
|
|
// Лента: текст прижат к низу, старые строки уходят вверх и обрезаются маской
|
|
|
|
|
|
var messagesGO = new GameObject("Messages", typeof(RectTransform), typeof(RectMask2D));
|
|
|
|
|
|
RectTransform messages = messagesGO.GetComponent<RectTransform>();
|
|
|
|
|
|
messages.SetParent(panel, false);
|
|
|
|
|
|
messages.anchorMin = Vector2.zero;
|
|
|
|
|
|
messages.anchorMax = Vector2.one;
|
|
|
|
|
|
messages.offsetMin = new Vector2(14, 86);
|
|
|
|
|
|
messages.offsetMax = new Vector2(-14, -74);
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform messagesText = CreateTextRect(messages, "MessagesText", "", 24, TextAlignmentOptions.BottomLeft);
|
|
|
|
|
|
TMP_Text tmp = messagesText.GetComponent<TMP_Text>();
|
|
|
|
|
|
tmp.overflowMode = TextOverflowModes.Overflow;
|
|
|
|
|
|
chat.messagesText = tmp;
|
|
|
|
|
|
|
|
|
|
|
|
// Поле ввода
|
|
|
|
|
|
GameObject inputGO = TMP_DefaultControls.CreateInputField(new TMP_DefaultControls.Resources());
|
|
|
|
|
|
inputGO.name = "InputField";
|
|
|
|
|
|
RectTransform inputRect = inputGO.GetComponent<RectTransform>();
|
|
|
|
|
|
inputRect.SetParent(panel, false);
|
|
|
|
|
|
SetRect(inputRect, Vector2.zero, new Vector2(1, 0), new Vector2(0.5f, 0), Vector2.zero, Vector2.zero);
|
|
|
|
|
|
inputRect.offsetMin = new Vector2(12, 12);
|
|
|
|
|
|
inputRect.offsetMax = new Vector2(-124, 74);
|
|
|
|
|
|
inputGO.GetComponent<Image>().color = new Color(0.12f, 0.13f, 0.17f);
|
|
|
|
|
|
|
|
|
|
|
|
TMP_InputField input = inputGO.GetComponent<TMP_InputField>();
|
|
|
|
|
|
input.pointSize = 26;
|
|
|
|
|
|
input.textComponent.color = Color.white;
|
|
|
|
|
|
((TMP_Text)input.placeholder).text = "Введите сообщение...";
|
|
|
|
|
|
((TMP_Text)input.placeholder).color = new Color(1f, 1f, 1f, 0.35f);
|
|
|
|
|
|
chat.inputField = input;
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform send = CreateButton(panel, "SendButton", ">", new Color(0.2f, 0.45f, 0.85f), out _);
|
|
|
|
|
|
SetRect(send, new Vector2(1, 0), new Vector2(1, 0), new Vector2(1, 0), new Vector2(-12, 12), new Vector2(100, 62));
|
|
|
|
|
|
chat.sendButton = send.GetComponent<Button>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- НИЖНЯЯ ПАНЕЛЬ ----------------
|
|
|
|
|
|
|
|
|
|
|
|
static void BuildNavBar(RectTransform canvasRect, WorldMapController controller)
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform bar = CreatePanel(canvasRect, "BottomNavBar", new Color(0.06f, 0.07f, 0.1f, 0.92f));
|
|
|
|
|
|
SetRect(bar, Vector2.zero, new Vector2(1, 0), new Vector2(0.5f, 0), Vector2.zero, Vector2.zero);
|
|
|
|
|
|
bar.offsetMin = new Vector2(ChatWidth + 24, 12);
|
|
|
|
|
|
bar.offsetMax = new Vector2(-12, 162);
|
|
|
|
|
|
|
|
|
|
|
|
var layout = bar.gameObject.AddComponent<HorizontalLayoutGroup>();
|
|
|
|
|
|
layout.padding = new RectOffset(10, 10, 10, 10);
|
|
|
|
|
|
layout.spacing = 10;
|
|
|
|
|
|
layout.childForceExpandWidth = true;
|
|
|
|
|
|
layout.childForceExpandHeight = true;
|
|
|
|
|
|
layout.childControlWidth = true;
|
|
|
|
|
|
layout.childControlHeight = true;
|
|
|
|
|
|
|
|
|
|
|
|
Color navColor = new Color(0.14f, 0.16f, 0.22f);
|
|
|
|
|
|
controller.worldMapNavButton = CreateButton(bar, "Nav_WorldMap", "Карта мира", navColor, out _).GetComponent<Button>();
|
|
|
|
|
|
controller.eventsNavButton = CreateButton(bar, "Nav_Events", "События", navColor, out _).GetComponent<Button>();
|
|
|
|
|
|
controller.circleNavButton = CreateButton(bar, "Nav_Circle", "Круг", navColor, out _).GetComponent<Button>();
|
|
|
|
|
|
controller.settlementNavButton = CreateButton(bar, "Nav_Settlement", "Поселение", new Color(0.18f, 0.25f, 0.45f), out _).GetComponent<Button>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- РЕЙТИНГ ----------------
|
|
|
|
|
|
|
|
|
|
|
|
static readonly Color RatingBg = new Color(0.04f, 0.06f, 0.1f, 0.97f);
|
|
|
|
|
|
static readonly Color RatingGold = new Color(0.95f, 0.8f, 0.5f);
|
|
|
|
|
|
|
|
|
|
|
|
const float RatingTableLeft = 340f;
|
|
|
|
|
|
const float RatingTableRight = 25f;
|
|
|
|
|
|
|
|
|
|
|
|
static RatingPanel BuildRatingPanel(RectTransform canvasRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform panel = CreatePanel(canvasRect, "RatingPanel", RatingBg);
|
|
|
|
|
|
SetRect(panel, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(1640, 920));
|
|
|
|
|
|
RatingPanel rating = panel.gameObject.AddComponent<RatingPanel>();
|
|
|
|
|
|
|
|
|
|
|
|
// Заголовок-баннер
|
|
|
|
|
|
RectTransform banner = CreatePanel(panel, "TitleBanner", new Color(0.12f, 0.25f, 0.55f));
|
|
|
|
|
|
SetRect(banner, new Vector2(0.5f, 1), new Vector2(0.5f, 1), new Vector2(0.5f, 1), new Vector2(0, -15), new Vector2(640, 90));
|
|
|
|
|
|
CreateText(banner, "Title", "Рейтинг", 60).color = RatingGold;
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform close = CreateButton(panel, "CloseButton", "X", new Color(0.35f, 0.15f, 0.15f), out _);
|
|
|
|
|
|
SetRect(close, new Vector2(1, 1), new Vector2(1, 1), new Vector2(1, 1), new Vector2(-15, -15), new Vector2(80, 80));
|
|
|
|
|
|
rating.closeButton = close.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
// Разделы слева -- порядок совпадает с RatingCategory
|
|
|
|
|
|
string[] categories = { "Игроки", "Круги", "Мощь", "PvP", "Развитие", "Сезон" };
|
|
|
|
|
|
rating.categoryButtons = new Button[categories.Length];
|
|
|
|
|
|
for (int i = 0; i < categories.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform tab = CreateButton(panel, "Category_" + i, categories[i], new Color(0.1f, 0.12f, 0.17f), out _);
|
|
|
|
|
|
SetRect(tab, new Vector2(0, 1), new Vector2(0, 1), new Vector2(0, 1), new Vector2(25, -130 - i * 112), new Vector2(290, 100));
|
|
|
|
|
|
rating.categoryButtons[i] = tab.GetComponent<Button>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Таблица
|
|
|
|
|
|
var tableGO = new GameObject("Table", typeof(RectTransform));
|
|
|
|
|
|
RectTransform table = tableGO.GetComponent<RectTransform>();
|
|
|
|
|
|
table.SetParent(panel, false);
|
|
|
|
|
|
table.anchorMin = Vector2.zero;
|
|
|
|
|
|
table.anchorMax = Vector2.one;
|
|
|
|
|
|
table.offsetMin = new Vector2(RatingTableLeft, 110);
|
|
|
|
|
|
table.offsetMax = new Vector2(-RatingTableRight, -130);
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform header = CreatePanel(table, "Header", new Color(0.08f, 0.1f, 0.15f));
|
|
|
|
|
|
SetRect(header, new Vector2(0, 1), new Vector2(1, 1), new Vector2(0.5f, 1), Vector2.zero, new Vector2(0, 50));
|
|
|
|
|
|
Color headerColor = new Color(0.8f, 0.82f, 0.88f);
|
|
|
|
|
|
PlaceInRow(CreateTextRect(header, "Place", "Место", 26), 0, 140, 50).GetComponent<TMP_Text>().color = headerColor;
|
|
|
|
|
|
TMP_Text nameHeader = PlaceInRow(CreateTextRect(header, "Name", "Игрок", 26, TextAlignmentOptions.Left), 225, 330, 50).GetComponent<TMP_Text>();
|
|
|
|
|
|
nameHeader.color = headerColor;
|
|
|
|
|
|
rating.nameColumnHeader = nameHeader;
|
|
|
|
|
|
TMP_Text circleHeader = PlaceInRow(CreateTextRect(header, "Circle", "Круг", 26, TextAlignmentOptions.Left), 625, 320, 50).GetComponent<TMP_Text>();
|
|
|
|
|
|
circleHeader.color = headerColor;
|
|
|
|
|
|
rating.circleColumnHeader = circleHeader;
|
|
|
|
|
|
PlaceInRow(CreateTextRect(header, "Power", "Мощь", 26), 950, 220, 50).GetComponent<TMP_Text>().color = headerColor;
|
|
|
|
|
|
|
|
|
|
|
|
rating.rows = new RatingRowView[RatingPanel.PageSize];
|
|
|
|
|
|
for (int i = 0; i < rating.rows.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
rating.rows[i] = BuildRatingRow(table, i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rating.emptyText = CreateText(table, "EmptyText", "Раздел в разработке", 40);
|
|
|
|
|
|
rating.emptyText.gameObject.SetActive(false);
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform status = CreateTextRect(panel, "StatusText", "", 26, TextAlignmentOptions.Left);
|
|
|
|
|
|
SetRect(status, Vector2.zero, Vector2.zero, Vector2.zero, new Vector2(RatingTableLeft, 30), new Vector2(520, 60));
|
|
|
|
|
|
rating.statusText = status.GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
// Страницы: < 1 2 3 4 5 > -- по центру под таблицей (а не под всей панелью)
|
|
|
|
|
|
float tableCenterX = (RatingTableLeft - RatingTableRight) / 2f;
|
|
|
|
|
|
Color pageColor = new Color(0.1f, 0.12f, 0.17f);
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform prev = CreateButton(panel, "PrevPage", "<", pageColor, out _);
|
|
|
|
|
|
SetRect(prev, new Vector2(0.5f, 0), new Vector2(0.5f, 0), new Vector2(0.5f, 0), new Vector2(tableCenterX - 240, 25), new Vector2(64, 64));
|
|
|
|
|
|
rating.prevPageButton = prev.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
rating.pageButtons = new Button[5];
|
|
|
|
|
|
for (int i = 0; i < rating.pageButtons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform page = CreateButton(panel, "Page_" + i, (i + 1).ToString(), pageColor, out _);
|
|
|
|
|
|
SetRect(page, new Vector2(0.5f, 0), new Vector2(0.5f, 0), new Vector2(0.5f, 0), new Vector2(tableCenterX - 150 + i * 75, 25), new Vector2(64, 64));
|
|
|
|
|
|
rating.pageButtons[i] = page.GetComponent<Button>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform next = CreateButton(panel, "NextPage", ">", pageColor, out _);
|
|
|
|
|
|
SetRect(next, new Vector2(0.5f, 0), new Vector2(0.5f, 0), new Vector2(0.5f, 0), new Vector2(tableCenterX + 240, 25), new Vector2(64, 64));
|
|
|
|
|
|
rating.nextPageButton = next.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
panel.gameObject.SetActive(false);
|
|
|
|
|
|
return rating;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static RatingRowView BuildRatingRow(RectTransform table, int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
const float rowHeight = 54f;
|
|
|
|
|
|
var view = new RatingRowView();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform row = CreatePanel(table, "Row_" + (index + 1), new Color(0.07f, 0.09f, 0.13f));
|
|
|
|
|
|
SetRect(row, new Vector2(0, 1), new Vector2(1, 1), new Vector2(0.5f, 1), new Vector2(0, -56 - index * 58), new Vector2(0, rowHeight));
|
|
|
|
|
|
view.root = row.gameObject;
|
|
|
|
|
|
view.background = row.GetComponent<Image>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform medal = CreatePanel(row, "Medal", Color.white);
|
|
|
|
|
|
PlaceInRow(medal, 45, 50, 50);
|
|
|
|
|
|
view.medal = medal.GetComponent<Image>();
|
|
|
|
|
|
view.placeText = PlaceInRow(CreateTextRect(row, "Place", "1", 30), 0, 140, rowHeight).GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform avatar = CreatePanel(row, "Avatar", Color.gray);
|
|
|
|
|
|
PlaceInRow(avatar, 150, 48, 48);
|
|
|
|
|
|
view.avatar = avatar.GetComponent<Image>();
|
|
|
|
|
|
view.avatarLetter = CreateText(avatar, "Letter", "В", 28);
|
|
|
|
|
|
|
|
|
|
|
|
view.nameText = PlaceInRow(CreateTextRect(row, "Name", "Игрок", 30, TextAlignmentOptions.Left), 225, 330, rowHeight).GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform circleBanner = CreatePanel(row, "CircleBanner", Color.blue);
|
|
|
|
|
|
PlaceInRow(circleBanner, 570, 36, 46);
|
|
|
|
|
|
view.circleBanner = circleBanner.GetComponent<Image>();
|
|
|
|
|
|
view.circleText = PlaceInRow(CreateTextRect(row, "Circle", "Круг", 28, TextAlignmentOptions.Left), 625, 320, rowHeight).GetComponent<TMP_Text>();
|
|
|
|
|
|
|
|
|
|
|
|
TMP_Text power = PlaceInRow(CreateTextRect(row, "Power", "0", 28), 950, 220, rowHeight).GetComponent<TMP_Text>();
|
|
|
|
|
|
power.color = RatingGold;
|
|
|
|
|
|
view.powerText = power;
|
|
|
|
|
|
|
|
|
|
|
|
RectTransform inspect = CreateButton(row, "InspectButton", "?", new Color(0.18f, 0.2f, 0.27f), out _);
|
|
|
|
|
|
PlaceInRow(inspect, 1190, 56, 44);
|
|
|
|
|
|
view.inspectButton = inspect.GetComponent<Button>();
|
|
|
|
|
|
|
|
|
|
|
|
return view;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Элемент строки: прижат к левому краю строки с отступом x, по вертикали по центру
|
|
|
|
|
|
static RectTransform PlaceInRow(RectTransform rt, float x, float width, float height)
|
|
|
|
|
|
{
|
|
|
|
|
|
SetRect(rt, new Vector2(0, 0.5f), new Vector2(0, 0.5f), new Vector2(0, 0.5f), new Vector2(x, 0), new Vector2(width, height));
|
|
|
|
|
|
return rt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void SetRect(RectTransform rt, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 position, Vector2 size)
|
|
|
|
|
|
{
|
|
|
|
|
|
rt.anchorMin = anchorMin;
|
|
|
|
|
|
rt.anchorMax = anchorMax;
|
|
|
|
|
|
rt.pivot = pivot;
|
|
|
|
|
|
rt.sizeDelta = size;
|
|
|
|
|
|
rt.anchoredPosition = position;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- BUILD SETTINGS ----------------
|
|
|
|
|
|
|
|
|
|
|
|
static void UpdateBuildSettings()
|
|
|
|
|
|
{
|
|
|
|
|
|
var scenes = new List<EditorBuildSettingsScene>
|
|
|
|
|
|
{
|
|
|
|
|
|
new EditorBuildSettingsScene(CityScenePath, true),
|
|
|
|
|
|
new EditorBuildSettingsScene(WorldMapScenePath, true)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Остальные уже добавленные сцены сохраняем (кроме удалённых файлов, например старой Battle)
|
|
|
|
|
|
foreach (var existing in EditorBuildSettings.scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (existing.path == CityScenePath || existing.path == WorldMapScenePath) continue;
|
|
|
|
|
|
if (!File.Exists(existing.path)) continue;
|
|
|
|
|
|
scenes.Add(existing);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorBuildSettings.scenes = scenes.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- КНОПКА В ГОРОДЕ ----------------
|
|
|
|
|
|
|
|
|
|
|
|
static void HookUpCityBattleButton()
|
|
|
|
|
|
{
|
|
|
|
|
|
var city = EditorSceneManager.OpenScene(CityScenePath, OpenSceneMode.Single);
|
|
|
|
|
|
|
|
|
|
|
|
GameObject navBattle = GameObject.Find("Nav_Battle");
|
|
|
|
|
|
if (navBattle == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[КАРТА] В сцене MVP1 не найден объект Nav_Battle -- повесь OpenBattleButton на кнопку БОЙ вручную.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (navBattle.GetComponent<OpenBattleButton>() == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Undo.AddComponent<OpenBattleButton>(navBattle); // RequireComponent сам добавит Button, если его нет
|
|
|
|
|
|
EditorSceneManager.MarkSceneDirty(city);
|
|
|
|
|
|
EditorSceneManager.SaveScene(city);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- HELPERS ----------------
|
|
|
|
|
|
|
|
|
|
|
|
static RectTransform CreatePanel(RectTransform parent, string name, Color color)
|
|
|
|
|
|
{
|
|
|
|
|
|
var go = new GameObject(name, typeof(RectTransform), typeof(Image));
|
|
|
|
|
|
go.transform.SetParent(parent, false);
|
|
|
|
|
|
go.GetComponent<Image>().color = color;
|
|
|
|
|
|
return go.GetComponent<RectTransform>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static RectTransform CreateCenterPanel(RectTransform parent, string name, Vector2 size)
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform rt = CreatePanel(parent, name, new Color(0.05f, 0.05f, 0.07f, 0.94f));
|
|
|
|
|
|
rt.anchorMin = rt.anchorMax = new Vector2(0.5f, 0.5f);
|
|
|
|
|
|
rt.sizeDelta = size;
|
|
|
|
|
|
return rt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static RectTransform CreateTextRect(RectTransform parent, string name, string content, int fontSize,
|
|
|
|
|
|
TextAlignmentOptions alignment = TextAlignmentOptions.Center)
|
|
|
|
|
|
{
|
|
|
|
|
|
var go = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI));
|
|
|
|
|
|
go.transform.SetParent(parent, false);
|
|
|
|
|
|
var tmp = go.GetComponent<TextMeshProUGUI>();
|
|
|
|
|
|
tmp.text = content;
|
|
|
|
|
|
tmp.fontSize = fontSize;
|
|
|
|
|
|
tmp.color = Color.white;
|
|
|
|
|
|
tmp.alignment = alignment;
|
|
|
|
|
|
tmp.raycastTarget = false;
|
|
|
|
|
|
RectTransform rt = go.GetComponent<RectTransform>();
|
|
|
|
|
|
rt.anchorMin = Vector2.zero;
|
|
|
|
|
|
rt.anchorMax = Vector2.one;
|
|
|
|
|
|
rt.offsetMin = Vector2.zero;
|
|
|
|
|
|
rt.offsetMax = Vector2.zero;
|
|
|
|
|
|
return rt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static TMP_Text CreateText(RectTransform parent, string name, string content, int fontSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
return CreateTextRect(parent, name, content, fontSize).GetComponent<TMP_Text>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static RectTransform CreateButton(RectTransform parent, string name, string label, Color color, out TMP_Text labelText)
|
|
|
|
|
|
{
|
|
|
|
|
|
var 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>();
|
|
|
|
|
|
labelText = CreateText(rt, "Label", label, 36);
|
|
|
|
|
|
return rt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void StyleSlider(GameObject sliderGO)
|
|
|
|
|
|
{
|
|
|
|
|
|
Image[] images = sliderGO.GetComponentsInChildren<Image>();
|
|
|
|
|
|
foreach (var img in images)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (img.name == "Background") img.color = new Color(0.25f, 0.25f, 0.28f);
|
|
|
|
|
|
else if (img.name == "Fill") img.color = new Color(0.3f, 0.55f, 1f);
|
|
|
|
|
|
else if (img.name == "Handle") img.color = Color.white;
|
|
|
|
|
|
}
|
|
|
|
|
|
// Ручка крупнее -- удобнее тянуть пальцем
|
|
|
|
|
|
Transform handle = sliderGO.transform.Find("Handle Slide Area/Handle");
|
|
|
|
|
|
if (handle != null) ((RectTransform)handle).sizeDelta = new Vector2(50, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void AnchorStretch(RectTransform rt, bool top, float height)
|
|
|
|
|
|
{
|
|
|
|
|
|
float y = top ? 1 : 0;
|
|
|
|
|
|
rt.anchorMin = new Vector2(0, y);
|
|
|
|
|
|
rt.anchorMax = new Vector2(1, y);
|
|
|
|
|
|
rt.pivot = new Vector2(0.5f, y);
|
|
|
|
|
|
rt.sizeDelta = new Vector2(0, height);
|
|
|
|
|
|
rt.anchoredPosition = Vector2.zero;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void AnchorSide(RectTransform rt, bool left, Vector2 size, float offset)
|
|
|
|
|
|
{
|
|
|
|
|
|
float x = left ? 0 : 1;
|
|
|
|
|
|
rt.anchorMin = new Vector2(x, 0.5f);
|
|
|
|
|
|
rt.anchorMax = new Vector2(x, 0.5f);
|
|
|
|
|
|
rt.pivot = new Vector2(x, 0.5f);
|
|
|
|
|
|
rt.sizeDelta = size;
|
|
|
|
|
|
rt.anchoredPosition = new Vector2(left ? offset : -offset, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Растянуть по ширине родителя, прижать к верху с отступом
|
|
|
|
|
|
static void AnchorTop(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 AnchorBottom(RectTransform rt, Vector2 size, Vector2 offset)
|
|
|
|
|
|
{
|
|
|
|
|
|
rt.anchorMin = rt.anchorMax = new Vector2(0.5f, 0);
|
|
|
|
|
|
rt.pivot = new Vector2(0.5f, 0);
|
|
|
|
|
|
rt.sizeDelta = size;
|
|
|
|
|
|
rt.anchoredPosition = offset;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|