using UnityEngine; using UnityEngine.UI; // Общая основа всех панелей HUD. // Каждая панель (Profile, Quests, Shop...) наследуется от BasePanel и реализует Build(): // "нарисуй своё содержимое в root". Перерисовка происходит сама: // - при открытии панели, // - когда GameProgress сообщает об изменениях (получил награду, обучил войска и т.д.). // Tick() вызывается 2 раза в секунду -- для таймеров, без полной перерисовки. public abstract class BasePanel : MonoBehaviour { protected GameProgress GP { get { return GameProgress.Instance; } } RectTransform content; ScrollRect scroll; bool needRebuild; bool resetScroll; float nextTick; // false -- панель НЕ перерисовывается от чужих изменений (нужно для ползунков в Настройках) protected virtual bool RebuildOnChange { get { return true; } } protected virtual void OnEnable() { if (RebuildOnChange) GP.OnChanged += RequestRebuild; needRebuild = true; resetScroll = true; } protected virtual void OnDisable() { if (GameProgress.Instance != null) GameProgress.Instance.OnChanged -= RequestRebuild; } public void RequestRebuild() { needRebuild = true; } void Update() { if (needRebuild) { needRebuild = false; Rebuild(); } if (Time.unscaledTime >= nextTick) { nextTick = Time.unscaledTime + 0.5f; Tick(); } Frame(); } RectTransform Content { get { if (content == null) { var t = transform.Find("Content"); if (t == null) { // запасной вариант для старых панелей без Content var body = transform.Find("Body"); if (body != null) body.gameObject.SetActive(false); t = UIKit.Stretch(UIKit.Make("Content", transform), 24, 130, 24, 24); } content = (RectTransform)t; } return content; } } void Rebuild() { float pos = (scroll != null && !resetScroll) ? scroll.verticalNormalizedPosition : 1f; resetScroll = false; scroll = null; UIKit.Clear(Content); Build(Content); if (scroll != null) { Canvas.ForceUpdateCanvases(); scroll.verticalNormalizedPosition = pos; } } // Прокручиваемый список на всю панель (позиция прокрутки сохраняется между перерисовками) protected RectTransform ScrollList(Transform parent, float spacing = 14) { return UIKit.ScrollList(parent, out scroll, spacing); } protected abstract void Build(RectTransform root); protected virtual void Tick() { } protected virtual void Frame() { } // каждый кадр -- для плавного движения (армии на карте) // Открыть другую панель (например, из "Боя" перейти в "Войска") protected void OpenPanel(string id) { if (UIPanelManager.Instance != null) UIPanelManager.Instance.Open(id); } }