Files
crtr/Assets/Cryville/Crtr/UI/Dialog.cs

88 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using TMPro;
using UnityEngine;
namespace Cryville.Crtr.UI {
public class Dialog : MonoBehaviour {
static Dialog _instance;
[SerializeField] CanvasGroup m_group;
[SerializeField] AnimationCurve m_fadeCurve;
[SerializeField] TextMeshProUGUI m_msgText;
[SerializeField] TextMeshProUGUI m_button0Text;
[SerializeField] TextMeshProUGUI m_button1Text;
[SerializeField] GameObject m_button1;
float _fadeDuration;
static readonly Queue<DialogEntry> _queue = new();
struct DialogEntry {
public Action<int> callback;
public string message;
public string action0;
public string action1;
}
void Awake() {
_instance = this;
_fadeDuration = m_fadeCurve[m_fadeCurve.length - 1].time;
}
float _timer;
DialogEntry? _cur;
static bool _suppressed;
void Update() {
if (_cur == null) {
if (_timer > 0) {
_timer -= Time.deltaTime;
if (_timer < 0) {
_timer = 0;
m_group.gameObject.SetActive(false);
}
m_group.alpha = m_fadeCurve.Evaluate(_timer);
}
if (_queue.Count > 0 && !_suppressed) {
m_group.gameObject.SetActive(true);
_cur = _queue.Dequeue();
m_msgText.text = _cur.Value.message;
m_button0Text.text = _cur.Value.action0;
m_button1Text.text = _cur.Value.action1;
m_button1.SetActive(_cur.Value.action1 != null);
}
}
else {
if (_timer < _fadeDuration) {
_timer += Time.deltaTime;
if (_timer > _fadeDuration) _timer = _fadeDuration;
m_group.alpha = m_fadeCurve.Evaluate(_timer);
}
}
}
public void OnButton(int id) {
if (_cur == null) return;
_cur.Value.callback?.Invoke(id);
_cur = null;
}
public static void Suppress() {
_suppressed = true;
if (_instance._cur != null) {
_queue.Enqueue(_instance._cur.Value);
_instance._cur = null;
}
}
public static void Release() {
_suppressed = false;
}
public static void Show(Action<int> callback, string message, string action0 = "OK", string action1 = null) {
_queue.Enqueue(new DialogEntry { callback = callback, message = message, action0 = action0, action1 = action1 });
}
public static int ShowAndWait(string message, string action0 = "OK", string action1 = null) {
using var ev = new AutoResetEvent(false);
int result = 0;
_queue.Enqueue(new DialogEntry {
callback = r => { result = r; ev.Set(); },
message = message, action0 = action0, action1 = action1,
});
ev.WaitOne();
return result;
}
}
}