revival/game/Assets/Scripts/Dialogue/DialogueUI.cs

128 lines
2.9 KiB
C#

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 float _fadeTime;
[SerializeField] private CanvasGroup _dialogueGroup;
[SerializeField] private TMP_Text _text;
[SerializeField] private GameObject _portrait;
private bool _dismissed;
private void OnEnable()
{
_dialogue.onDialogueLine += (_, dl) => ShowLine(dl);
_text.text = string.Empty;
_portrait.SetActive(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
float a = 0f;
_dialogueGroup.alpha = a;
_text.text = text;
_portrait.SetActive( true );
while ( a < 1f )
{
yield return null;
a += Time.deltaTime / _fadeTime;
_dialogueGroup.alpha = a;
}
_dialogueGroup.alpha = 1f;
// wait until timeout of dismissal
var timer = 0f;
while (!_dismissed && timer < duration)
{
timer += Time.deltaTime;
// wait for next frame
yield return null;
}
while ( a > 0f )
{
yield return null;
a -= Time.deltaTime / _fadeTime;
_dialogueGroup.alpha = a;
}
_dialogueGroup.alpha = 0f;
// hide ui elements
HideSubtitle();
_dismissed = false;
}
private void HideSubtitle()
{
_text.text = string.Empty;
_portrait.SetActive( 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