using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; #if UNITY_EDITOR using UnityEditor; #endif // updates visible subtitle text and a character portrait of the speaker public class DialogueUI : MonoBehaviour { [SerializeField] private DialogueSystem _dialogue; [SerializeField] private TMP_Text _text; [SerializeField] private Image _portrait; private bool _dismissed; private void OnEnable() { _dialogue.onDialogueLine += (_, dl) => ShowLine(dl); _text.text = string.Empty; _portrait.enabled = false; } public void Dismiss() { _dismissed = true; } private IEnumerator _subtitleRoutine; private void ShowLine(DialogueLine line) { // there is a line currently being shown, abort its coroutine and hide ui elements if (_subtitleRoutine != null && _text.text != null) { HideSubtitle(); StopCoroutine(_subtitleRoutine); } _subtitleRoutine = ShowLineCR(line.text, line.duration); StartCoroutine(_subtitleRoutine); } private IEnumerator ShowLineCR(string text, float duration) { // update text and show portrait _text.text = text; _portrait.enabled = true; // wait until timeout of dismissal var timer = 0f; while (!_dismissed && timer < duration) { timer += Time.deltaTime; // wait for next frame yield return null; } // hide ui elements HideSubtitle(); _dismissed = false; } private void HideSubtitle() { _text.text = string.Empty; _portrait.enabled = false; } } #region Editor #if UNITY_EDITOR [CustomEditor(typeof(DialogueUI))] public class DialogueUIEditor : Editor { private DialogueUI _dialogueUI; private void OnEnable() { _dialogueUI = target as DialogueUI; } public override void OnInspectorGUI() { base.OnInspectorGUI(); if (!Application.isPlaying) return; if (GUILayout.Button("Dismiss")) { _dialogueUI.Dismiss(); } } } #endif #endregion