using System.Collections.Generic; using TMPro; using UnityEngine; namespace NightclubArcadia.Skills { /// /// Skills tab content. Rebuilds the list from SkillDatabase.All + /// PlayerSkills.GetRank on each show. No change event on PlayerSkills — /// refresh on show is deliberate (menu is modal; ranks cannot change while open). /// public sealed class SkillsPanelView : MonoBehaviour { [SerializeField] RectTransform contentRoot; [SerializeField] SkillRowView rowPrefab; [SerializeField] TMP_Text axisHeaderPrefab; [SerializeField] int displayMaxRank = 6; readonly List spawned = new List(); /// /// Wired from MenuTabBar TabEntry.onShown in the Inspector. /// public void Refresh() { Clear(); var runtime = SkillRuntime.Instance; if (runtime == null || runtime.Database == null || runtime.Skills == null) { return; } if (contentRoot == null || rowPrefab == null) { Debug.LogWarning($"[{nameof(SkillsPanelView)}] Missing contentRoot or rowPrefab.", this); return; } SkillAxis? currentAxis = null; foreach (var def in runtime.Database.All) { if (def == null || string.IsNullOrEmpty(def.Id)) { continue; } if (currentAxis == null || currentAxis.Value != def.Axis) { currentAxis = def.Axis; SpawnAxisHeader(def.Axis); } var rank = runtime.Skills.GetRank(def.Id); var row = Instantiate(rowPrefab, contentRoot); row.gameObject.SetActive(true); row.Bind(def, rank, displayMaxRank); spawned.Add(row.gameObject); } } void SpawnAxisHeader(SkillAxis axis) { if (axisHeaderPrefab == null) { return; } var header = Instantiate(axisHeaderPrefab, contentRoot); header.gameObject.SetActive(true); header.text = axis.ToString().ToUpperInvariant(); spawned.Add(header.gameObject); } void Clear() { for (var i = 0; i < spawned.Count; i++) { if (spawned[i] != null) { Destroy(spawned[i]); } } spawned.Clear(); } } }