using UnityEngine; using UnityEngine.UI; public class DialogueUI : MonoBehaviour { private const string PanelKey = "DialogueUI"; public static DialogueUI Instance { get; private set; } [SerializeField] private GameObject dialoguePanel; [SerializeField] private Text npcNameText; [SerializeField] private Text dialogueText; [SerializeField] private Transform optionsRoot; [SerializeField] private Button optionButtonTemplate; [SerializeField] private Button closeButton; private NPC currentNpc; public bool IsOpen => dialoguePanel != null && dialoguePanel.activeSelf; public void Configure( GameObject panel, Text nameLabel, Text messageLabel, Transform responseRoot, Button responseTemplate, Button closePanelButton) { dialoguePanel = panel; npcNameText = nameLabel; dialogueText = messageLabel; optionsRoot = responseRoot; optionButtonTemplate = responseTemplate; closeButton = closePanelButton; if (dialoguePanel != null) { dialoguePanel.SetActive(false); } if (optionButtonTemplate != null) { optionButtonTemplate.gameObject.SetActive(false); } } private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; if (closeButton != null) { closeButton.onClick.RemoveListener(CloseDialogue); closeButton.onClick.AddListener(CloseDialogue); } } public void ShowDialogue(NPC npc) { if (npc == null || dialoguePanel == null) { return; } if (Inventory.Instance != null && Inventory.Instance.IsOpen) { Inventory.Instance.CloseInventory(); } if (NoteUI.Instance != null && NoteUI.Instance.IsOpen) { NoteUI.Instance.CloseNote(); } currentNpc = npc; npcNameText.text = npc.NPCName; dialogueText.text = npc.OpeningLine; dialoguePanel.SetActive(true); RebuildOptions(); GameUIState.SetPanelOpen(PanelKey, true); } public void ShowFollowUp(string speakerName, string message) { if (dialoguePanel == null) { return; } npcNameText.text = speakerName; dialogueText.text = message; ClearOptionButtons(); dialoguePanel.SetActive(true); GameUIState.SetPanelOpen(PanelKey, true); } public void CloseDialogue() { ClearOptionButtons(); if (dialoguePanel != null) { dialoguePanel.SetActive(false); } currentNpc = null; GameUIState.SetPanelOpen(PanelKey, false); } private void RebuildOptions() { ClearOptionButtons(); if (currentNpc == null || optionsRoot == null || optionButtonTemplate == null) { return; } foreach (var option in currentNpc.DialogueOptions) { var capturedOption = option; var optionButton = Instantiate(optionButtonTemplate, optionsRoot); optionButton.gameObject.SetActive(true); optionButton.onClick.RemoveAllListeners(); optionButton.onClick.AddListener(() => currentNpc.SelectOption(capturedOption)); optionButton.interactable = currentNpc.IsOptionAvailable(capturedOption); var label = optionButton.GetComponentInChildren(); if (label != null) { label.text = currentNpc.GetOptionLabel(capturedOption); label.color = optionButton.interactable ? Color.white : new Color(0.82f, 0.82f, 0.82f, 1f); } } } private void ClearOptionButtons() { if (optionsRoot == null || optionButtonTemplate == null) { return; } for (var i = optionsRoot.childCount - 1; i >= 0; i--) { var child = optionsRoot.GetChild(i); if (child == optionButtonTemplate.transform) { continue; } Destroy(child.gameObject); } } }