using UnityEngine; using TMPro; // Ресурс на верхней панели (этап 1): "запас / лимит" и прирост в час. // - Дерево, камень, металл, золото, еда, кристаллы: "820 / 1000" и строкой ниже "+50/ч" (у еды -- добыча минус расход); // - Люди: "300 / 350" (население / предел жилья) и прирост людей в час. // Числа без сокращений 1.2K / 1.5M: по документу нормальный масштаб -- сотни и тысячи. [RequireComponent(typeof(TMP_Text))] public class ResourceUIText : MonoBehaviour { public ResourceType resourceType; [Tooltip("Показывать лимит склада: \"820 / 1000\"")] public bool showCapacity = true; [Tooltip("Показывать прирост в час второй строкой: \"+50/ч\"")] public bool showRate = true; [Tooltip("Устарело (этап 1): сокращения 1.2K / 1.5M убраны")] [HideInInspector] public bool useShortFormat; private TMP_Text label; private float next; private string lastText; void Awake() { label = GetComponent(); // В сцене на ячейках дерева, камня, металла, золота и кристалла по ошибке висит второй такой же компонент // с типом "Люди" -- он перебивал число ресурса. Если рядом есть компонент с настоящим ресурсом -- выключаемся. if (resourceType == ResourceType.Population) { foreach (var other in GetComponents()) { if (other != this && other.resourceType != ResourceType.Population) { enabled = false; return; } } } } void OnEnable() { next = 0f; } void Update() { if (Time.unscaledTime < next) return; next = Time.unscaledTime + 0.5f; Refresh(); } void Refresh() { string text = BuildText(); if (text == lastText) return; lastText = text; label.text = text; } string BuildText() { // Люди -- из модуля Населения if (resourceType == ResourceType.Population && GameServices.TryGet(out IPopulation pop)) { string value = showCapacity ? $"{pop.Total} / {pop.HousingCap}" : pop.Total.ToString(); return showRate ? value + RateLine(pop.GrowthPerHour) : value; } if (!GameServices.TryGet(out IEconomy economy)) return "0"; int amount = Mathf.FloorToInt(economy.Get(resourceType)); float cap = economy.GetCapacity(resourceType); string main = showCapacity && !float.IsInfinity(cap) ? $"{amount} / {Mathf.RoundToInt(cap)}" : amount.ToString(); if (!showRate || resourceType == ResourceType.Power) return main; float rate = GameServices.TryGet(out IProduction production) ? production.RatePerHour(resourceType) : 0f; if (resourceType == ResourceType.Food && GameServices.TryGet(out IPopulation p)) rate -= p.FoodPerHour; if (resourceType == ResourceType.Gems) return main; // кристалл не добывается рабочими (разломы на карте мира) return main + RateLine(rate); } static string RateLine(float rate) { string color = rate < 0 ? "#ff8a80" : "#9be29b"; string sign = rate > 0 ? "+" : ""; return $"\n{sign}{rate:0.#}/ч"; } }