using System; using System.Collections.Generic; using System.Threading; using UnityEngine; using UnityEngine.UI; namespace Cryville.Crtr { public class Dialog : MonoBehaviour { static Dialog _instance; [SerializeField] CanvasGroup m_group; [SerializeField] Text m_msgText; [SerializeField] Text m_button0Text; [SerializeField] Text m_button1Text; [SerializeField] GameObject m_button1; [SerializeField] AnimationCurve m_fadeCurve; float _fadeDuration; static readonly Queue _queue = new Queue(); struct DialogEntry { public Action 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; var cb = _cur.Value.callback; if (cb != null) cb(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 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; } } } }