Files
ichni_Official/Assets/Scripts/NewStorySystem/Helper/StoryHelperTalk.cs
SoulliesOfficial 810d019619 剧情+对话完善
2026-07-21 15:24:42 -04:00

103 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using DG.Tweening;
using TMPro;
using UnityEngine;
namespace Ichni.Story
{
/// <summary>
/// 由 <see cref="StoryHelperController"/> 按需实例化的 Helper 专属对话气泡。
/// <para>每个实例只显示一条文本:淡入、停留、淡出后自动销毁,因此场景中不需要常驻气泡,
/// 也不会与通用 MessageBox 队列产生耦合。</para>
/// </summary>
[RequireComponent(typeof(CanvasGroup))]
public class StoryHelperTalk : MonoBehaviour
{
[SerializeField, Tooltip("显示 Helper 名称的文本。")]
private TMP_Text speakerText;
[SerializeField, Tooltip("显示随机 Helper 对话的文本。")]
private TMP_Text contentText;
[Header("Animation")]
[SerializeField, Min(0.01f), Tooltip("淡入与缩放入场时间。")]
private float showDuration = 0.18f;
[SerializeField, Min(0f), Tooltip("气泡完整显示后的停留时间。")]
private float visibleDuration = 4.5f;
[SerializeField, Min(0.01f), Tooltip("淡出与缩放退场时间。")]
private float hideDuration = 0.16f;
[SerializeField, Range(0.5f, 1f), Tooltip("入场与退场时相对原始大小的缩放比例。")]
private float initialScaleMultiplier = 0.92f;
/// <summary>气泡结束显示并准备销毁时触发,供创建者清理当前实例引用。</summary>
public event Action<StoryHelperTalk> Closed;
private CanvasGroup _canvasGroup;
private RectTransform _rectTransform;
private Sequence _sequence;
private Vector3 _baseScale;
private bool _isClosed;
private void Awake()
{
_canvasGroup = GetComponent<CanvasGroup>();
_rectTransform = transform as RectTransform;
_baseScale = _rectTransform != null ? _rectTransform.localScale : Vector3.one;
}
/// <summary>
/// 写入文本并播放完整的出现、停留与收回流程。
/// 所有 DOTween Sequence 均先 Pause再手动调用 Play符合项目约定。
/// </summary>
public void Show(string speaker, string content)
{
if (speakerText == null || contentText == null || _rectTransform == null)
{
Debug.LogWarning("[StoryHelperTalk] Prefab 未配置 Speaker Text、Content Text 或 RectTransform已取消显示。", this);
CloseImmediately();
return;
}
speakerText.text = speaker;
contentText.text = content;
_canvasGroup.alpha = 0f;
_rectTransform.localScale = _baseScale * initialScaleMultiplier;
_sequence?.Kill();
_sequence = DOTween.Sequence()
.Pause()
.SetUpdate(true)
.Append(_canvasGroup.DOFade(1f, showDuration))
.Join(_rectTransform.DOScale(_baseScale, showDuration).SetEase(Ease.OutBack))
.AppendInterval(visibleDuration)
.Append(_canvasGroup.DOFade(0f, hideDuration))
.Join(_rectTransform.DOScale(_baseScale * initialScaleMultiplier, hideDuration).SetEase(Ease.InQuad))
.OnComplete(CloseImmediately);
_sequence.Play();
}
/// <summary>
/// 立即关闭并销毁该运行时实例。再次点击 Helper 时会调用它,使旧文本不会与新文本叠加。
/// </summary>
public void CloseImmediately()
{
if (_isClosed)
return;
_isClosed = true;
_sequence?.Kill();
_sequence = null;
Closed?.Invoke(this);
Destroy(gameObject);
}
private void OnDestroy()
{
_sequence?.Kill();
}
}
}