157 lines
7.0 KiB
C#
157 lines
7.0 KiB
C#
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
// ОТЛАДОЧНАЯ ПАНЕЛЬ для проверки баланса: кнопка "DEV" слева на экране.
|
|
//
|
|
// Есть только в редакторе и в Development Build -- в релизную сборку этот файл не попадает совсем.
|
|
// "+1 час" не имеет своей логики: он двигает GameClock, и модули досчитывают время по своим обычным правилам,
|
|
// ровно как при возвращении игрока в игру. Поэтому проверяешь настоящие правила, а не кнопку.
|
|
//
|
|
// Перемотка действует на то, что берёт время из GameClock (сейчас -- Население). Походы и обучение
|
|
// войск пока идут по реальным часам.
|
|
public class DebugPanel : MonoBehaviour
|
|
{
|
|
static DebugPanel instance;
|
|
|
|
GameObject panel;
|
|
TextMeshProUGUI info;
|
|
float nextRefresh;
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
|
static void Create()
|
|
{
|
|
if (instance != null) return;
|
|
var go = new GameObject("DebugPanel", typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
|
DontDestroyOnLoad(go);
|
|
var canvas = go.GetComponent<Canvas>();
|
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
|
canvas.sortingOrder = 1500; // поверх HUD и окон
|
|
var scaler = go.GetComponent<CanvasScaler>();
|
|
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
|
scaler.referenceResolution = new Vector2(1920, 1080);
|
|
scaler.matchWidthOrHeight = 0.5f;
|
|
instance = go.AddComponent<DebugPanel>();
|
|
instance.Build();
|
|
}
|
|
|
|
void Build()
|
|
{
|
|
// Кнопка-переключатель слева посередине: там нет кнопок HUD
|
|
var toggle = UIKit.Button(transform, "DEV", new Color(0.55f, 0.15f, 0.55f, 0.85f), Toggle, 110, 64, 26);
|
|
var trt = (RectTransform)toggle.transform;
|
|
trt.anchorMin = trt.anchorMax = new Vector2(0, 0.5f);
|
|
trt.pivot = new Vector2(0, 0.5f);
|
|
trt.anchoredPosition = new Vector2(12, 0);
|
|
trt.sizeDelta = new Vector2(110, 64);
|
|
|
|
var card = UIKit.Card(transform, new Color(0.08f, 0.08f, 0.11f, 0.95f), 20, 10);
|
|
card.anchorMin = card.anchorMax = new Vector2(0, 0.5f);
|
|
card.pivot = new Vector2(0, 0.5f);
|
|
card.anchoredPosition = new Vector2(135, 0);
|
|
card.sizeDelta = new Vector2(620, 0);
|
|
card.gameObject.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
panel = card.gameObject;
|
|
|
|
var title = UIKit.Text(card, "ОТЛАДКА БАЛАНСА", 30, UIKit.Theme.Gold, TextAlignmentOptions.Center);
|
|
title.fontStyle = FontStyles.Bold;
|
|
|
|
info = UIKit.Text(card, "", 24, UIKit.Theme.Text);
|
|
|
|
var row1 = UIKit.Row(card, 70, 10);
|
|
Btn(row1, "+1 час", UIKit.Theme.Blue, () => GameClock.Advance(3600));
|
|
Btn(row1, "+10 часов", UIKit.Theme.Blue, () => GameClock.Advance(36000));
|
|
|
|
var row2 = UIKit.Row(card, 70, 10);
|
|
Btn(row2, "+100 всех ресурсов", UIKit.Theme.Green, AddAllResources);
|
|
Btn(row2, "+1000 еды", UIKit.Theme.Green, () => AddResource(ResourceType.Food, 1000));
|
|
|
|
var row3 = UIKit.Row(card, 70, 10);
|
|
Btn(row3, "Еда = 0", UIKit.Theme.Red, ZeroFood);
|
|
Btn(row3, "Сбросить перемотку", UIKit.Theme.Gray, () => { GameClock.ResetOffset(); Refresh(); });
|
|
|
|
var row4 = UIKit.Row(card, 70, 10);
|
|
Btn(row4, "Рабочие", UIKit.Theme.Blue, () => BuildingWindow.Open(null));
|
|
|
|
panel.SetActive(false);
|
|
}
|
|
|
|
static void Btn(Transform row, string label, Color color, System.Action onClick)
|
|
{
|
|
var b = UIKit.Button(row, label, color, onClick, -1, 70, 24);
|
|
UIKit.Size(b, -1, 70, 1);
|
|
}
|
|
|
|
void Toggle()
|
|
{
|
|
panel.SetActive(!panel.activeSelf);
|
|
if (panel.activeSelf) Refresh();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (panel == null || !panel.activeSelf || Time.unscaledTime < nextRefresh) return;
|
|
nextRefresh = Time.unscaledTime + 0.5f;
|
|
Refresh();
|
|
}
|
|
|
|
void Refresh()
|
|
{
|
|
if (info == null) return;
|
|
var sb = new System.Text.StringBuilder();
|
|
|
|
if (GameServices.TryGet(out IPopulation p))
|
|
{
|
|
sb.Append($"Население: <b>{p.Total}</b> / {p.HousingCap}\n");
|
|
sb.Append($" жители {p.Civilians}: на работе {p.Workers}, свободно {p.FreeWorkers} из {p.Workforce}; воины {p.Soldiers}\n");
|
|
sb.Append($"Еда в час: <color=#ff8a80>-{p.FoodPerHour:0.#}</color> прирост в час: +{p.GrowthPerHour:0.#}\n");
|
|
if (p.IsStarving) sb.Append("<color=#ff5252><b>ГОЛОД: еды не хватает, прирост остановлен</b></color>\n");
|
|
}
|
|
else sb.Append("Модуль Населения не зарегистрирован\n");
|
|
|
|
if (GameServices.TryGet(out IProduction prod))
|
|
sb.Append($"Добыча в час: еда +{prod.RatePerHour(ResourceType.Food):0.#}, дерево +{prod.RatePerHour(ResourceType.Wood):0.#}, " +
|
|
$"камень +{prod.RatePerHour(ResourceType.Stone):0.#}, металл +{prod.RatePerHour(ResourceType.Iron):0.#}, золото +{prod.RatePerHour(ResourceType.Gold):0.#}\n");
|
|
|
|
if (GameServices.TryGet(out IEconomy e))
|
|
sb.Append($"Склад: еда {e.Get(ResourceType.Food):0}/{Cap(e, ResourceType.Food)} дерево {e.Get(ResourceType.Wood):0}/{Cap(e, ResourceType.Wood)} " +
|
|
$"камень {e.Get(ResourceType.Stone):0}/{Cap(e, ResourceType.Stone)}\n");
|
|
else sb.Append("Экономика не найдена (нет ResourceManager на сцене)\n");
|
|
|
|
long off = GameClock.OffsetSeconds;
|
|
sb.Append(off > 0 ? $"Перемотано: +{off / 3600f:0.#} ч" : "Время: реальное");
|
|
info.text = sb.ToString();
|
|
}
|
|
|
|
static string Cap(IEconomy e, ResourceType t)
|
|
{
|
|
float c = e.GetCapacity(t);
|
|
return float.IsInfinity(c) ? "∞" : c.ToString("0");
|
|
}
|
|
|
|
void AddAllResources()
|
|
{
|
|
ResourceType[] types = { ResourceType.Wood, ResourceType.Food, ResourceType.Stone, ResourceType.Iron, ResourceType.Gold, ResourceType.Gems };
|
|
foreach (var t in types) AddResource(t, 100);
|
|
}
|
|
|
|
void AddResource(ResourceType type, float amount)
|
|
{
|
|
if (GameServices.TryGet(out IEconomy e)) e.Add(type, amount);
|
|
Refresh();
|
|
}
|
|
|
|
void ZeroFood()
|
|
{
|
|
if (GameServices.TryGet(out IEconomy e)) e.Add(ResourceType.Food, -e.Get(ResourceType.Food));
|
|
Refresh();
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
if (instance == this) instance = null;
|
|
}
|
|
}
|
|
#endif
|