172 lines
6.7 KiB
C#
172 lines
6.7 KiB
C#
#nullable enable
|
|
|
|
using System.Collections;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace ReplacedPerson.Runtime
|
|
{
|
|
[DisallowMultipleComponent]
|
|
public sealed class ReplacedBattlePhaseMotion : MonoBehaviour
|
|
{
|
|
private RectTransform? _panel;
|
|
private CanvasGroup? _group;
|
|
private Image? _background;
|
|
private Image? _accent;
|
|
private TMP_Text? _title;
|
|
private TMP_Text? _detail;
|
|
|
|
public bool IsVisible => _panel != null && _panel.gameObject.activeSelf;
|
|
public string CurrentTitle => _title?.text ?? string.Empty;
|
|
|
|
private void Awake()
|
|
{
|
|
CreateOverlay();
|
|
SetVisible(false);
|
|
}
|
|
|
|
public IEnumerator PlayStage(string title, string detail, Color accent, float holdSeconds = .68f)
|
|
{
|
|
if (!Prepare(title, detail, accent)) yield break;
|
|
yield return FadeIn();
|
|
yield return new WaitForSecondsRealtime(holdSeconds);
|
|
yield return FadeOut();
|
|
}
|
|
|
|
public IEnumerator PlayDie(string title, int finalFace, string result, Color accent)
|
|
{
|
|
if (!Prepare(title, "D6 ·", accent)) yield break;
|
|
yield return FadeIn();
|
|
for (var frame = 0; frame < 8; frame++)
|
|
{
|
|
if (_detail != null) _detail.text = "D6 " + ((frame * 5 + 2) % 6 + 1);
|
|
if (_panel != null) _panel.localRotation = Quaternion.Euler(0, 0, frame % 2 == 0 ? -1.2f : 1.2f);
|
|
yield return new WaitForSecondsRealtime(.065f);
|
|
}
|
|
if (_panel != null) _panel.localRotation = Quaternion.identity;
|
|
if (_detail != null) _detail.text = $"D6 {finalFace}\n{result}";
|
|
yield return new WaitForSecondsRealtime(.75f);
|
|
yield return FadeOut();
|
|
}
|
|
|
|
private bool Prepare(string title, string detail, Color accent)
|
|
{
|
|
if (_panel == null || _group == null || _background == null || _accent == null || _title == null || _detail == null)
|
|
return false;
|
|
_title.text = title;
|
|
_detail.text = detail;
|
|
_accent.color = accent;
|
|
_background.color = new Color(.035f, .041f, .043f, .96f);
|
|
_panel.localScale = Vector3.one * .92f;
|
|
_panel.localRotation = Quaternion.identity;
|
|
_group.alpha = 0f;
|
|
SetVisible(true);
|
|
_panel.SetAsLastSibling();
|
|
return true;
|
|
}
|
|
|
|
private IEnumerator FadeIn()
|
|
{
|
|
if (_panel == null || _group == null) yield break;
|
|
var elapsed = 0f;
|
|
const float duration = .16f;
|
|
while (elapsed < duration)
|
|
{
|
|
elapsed += Time.unscaledDeltaTime;
|
|
var t = 1f - Mathf.Pow(1f - Mathf.Clamp01(elapsed / duration), 3f);
|
|
_group.alpha = t;
|
|
_panel.localScale = Vector3.one * Mathf.Lerp(.92f, 1f, t);
|
|
yield return null;
|
|
}
|
|
_group.alpha = 1f;
|
|
_panel.localScale = Vector3.one;
|
|
}
|
|
|
|
private IEnumerator FadeOut()
|
|
{
|
|
if (_panel == null || _group == null) yield break;
|
|
var elapsed = 0f;
|
|
const float duration = .16f;
|
|
while (elapsed < duration)
|
|
{
|
|
elapsed += Time.unscaledDeltaTime;
|
|
var t = Mathf.Clamp01(elapsed / duration);
|
|
_group.alpha = 1f - t;
|
|
_panel.localScale = Vector3.one * Mathf.Lerp(1f, .97f, t);
|
|
yield return null;
|
|
}
|
|
SetVisible(false);
|
|
}
|
|
|
|
private void CreateOverlay()
|
|
{
|
|
var panelObject = new GameObject("ResolutionPhaseOverlay", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(CanvasGroup));
|
|
_panel = panelObject.GetComponent<RectTransform>();
|
|
_panel.SetParent(transform, false);
|
|
_panel.anchorMin = new Vector2(.25f, .37f);
|
|
_panel.anchorMax = new Vector2(.75f, .64f);
|
|
_panel.offsetMin = Vector2.zero;
|
|
_panel.offsetMax = Vector2.zero;
|
|
_background = panelObject.GetComponent<Image>();
|
|
_background.raycastTarget = false;
|
|
_group = panelObject.GetComponent<CanvasGroup>();
|
|
_group.blocksRaycasts = false;
|
|
_group.interactable = false;
|
|
|
|
var accentObject = new GameObject("Accent", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
|
|
var accentRect = accentObject.GetComponent<RectTransform>();
|
|
accentRect.SetParent(_panel, false);
|
|
accentRect.anchorMin = new Vector2(0, 0);
|
|
accentRect.anchorMax = new Vector2(0, 1);
|
|
accentRect.pivot = new Vector2(0, .5f);
|
|
accentRect.sizeDelta = new Vector2(9, 0);
|
|
_accent = accentObject.GetComponent<Image>();
|
|
_accent.raycastTarget = false;
|
|
|
|
var font = GetComponentInChildren<TMP_Text>(true)?.font;
|
|
_title = CreateText("Title", _panel, font, new Vector2(.08f, .55f), new Vector2(.92f, .92f), 31, FontStyles.Bold);
|
|
_detail = CreateText("Detail", _panel, font, new Vector2(.08f, .10f), new Vector2(.92f, .58f), 22, FontStyles.Normal);
|
|
_detail.enableAutoSizing = true;
|
|
_detail.fontSizeMin = 14;
|
|
_detail.fontSizeMax = 22;
|
|
}
|
|
|
|
private static TMP_Text CreateText(string name, Transform parent, TMP_FontAsset? font, Vector2 anchorMin,
|
|
Vector2 anchorMax, float fontSize, FontStyles style)
|
|
{
|
|
var textObject = new GameObject(name, typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI));
|
|
var rect = textObject.GetComponent<RectTransform>();
|
|
rect.SetParent(parent, false);
|
|
rect.anchorMin = anchorMin;
|
|
rect.anchorMax = anchorMax;
|
|
rect.offsetMin = Vector2.zero;
|
|
rect.offsetMax = Vector2.zero;
|
|
var text = textObject.GetComponent<TextMeshProUGUI>();
|
|
text.font = font;
|
|
text.fontSize = fontSize;
|
|
text.fontStyle = style;
|
|
text.alignment = TextAlignmentOptions.Center;
|
|
text.color = new Color(.95f, .93f, .87f, 1f);
|
|
text.raycastTarget = false;
|
|
return text;
|
|
}
|
|
|
|
private void SetVisible(bool visible)
|
|
{
|
|
if (_panel != null) _panel.gameObject.SetActive(visible);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (_panel != null)
|
|
{
|
|
_panel.localScale = Vector3.one;
|
|
_panel.localRotation = Quaternion.identity;
|
|
}
|
|
if (_group != null) _group.alpha = 0f;
|
|
SetVisible(false);
|
|
}
|
|
}
|
|
}
|