using NightclubArcadia.Dialogue; using TMPro; using UnityEngine; using Yarn.Unity; namespace NightclubArcadia.UI.Menu { /// /// Character tab stub: shows player name / alias from Yarn variable storage /// and an empty inventory placeholder. /// public sealed class CharacterPanelView : MonoBehaviour { [SerializeField] TMP_Text nameLabel; [SerializeField] TMP_Text aliasLabel; [SerializeField] TMP_Text inventoryPlaceholder; [SerializeField] DialogueRunner dialogueRunner; // No OnEnable refresh: panels are toggled via CanvasGroup, so OnEnable // fires exactly once during scene load — before the DialogueRunner has // initialised its variables. MenuTabBar calls Refresh on tab show, // which is both correctly timed and repeatable. public void Refresh() { if (dialogueRunner == null) { dialogueRunner = FindFirstObjectByType(); } var storage = dialogueRunner != null ? dialogueRunner.VariableStorage : null; if (nameLabel != null) { nameLabel.text = ReadString(storage, "$player_name_full", "Unknown"); } if (aliasLabel != null) { // $player_alias is a *smart* variable // <> // and Yarn's Unity runtime never assigns // VariableStorageBehaviour.SmartVariableEvaluator, so reading it // through TryGetValue always throws InvalidOperationException. // Derive it from $player_name with the same generator the Yarn // function wraps — deterministic, so the result is identical. var realName = ReadString(storage, "$player_name", string.Empty); aliasLabel.text = string.IsNullOrEmpty(realName) ? "—" : AliasNameGenerator.AliasName(realName); } if (inventoryPlaceholder != null) { inventoryPlaceholder.text = "Inventory — empty"; } } static string ReadString(VariableStorageBehaviour storage, string key, string fallback) { if (storage == null) { return fallback; } try { if (storage.TryGetValue(key, out var value) && !string.IsNullOrEmpty(value)) { return value; } } catch (System.InvalidOperationException) { // Smart variables, and variables read before the runner has a // compiled Program, throw rather than returning false. A HUD // panel showing a fallback string is the right failure mode. } return fallback; } } }