164 lines
4.2 KiB
C#
164 lines
4.2 KiB
C#
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<Text>();
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|