Files
ichni_Official/Assets/Scripts/UI/Elements/TextCatapult.cs
SoulliesOfficial 70b2a43824 update
2025-08-22 14:54:40 -04:00

122 lines
4.9 KiB
C#
Raw Permalink 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.Collections;
using System.Collections.Generic;
using DG.Tweening;
using TMPro;
using UnityEngine;
namespace Ichni.UI
{
public class TextCatapult : MonoBehaviour
{
[Header("UI 元素")] [Tooltip("第一个文本组件")] [SerializeField]
private TMP_Text textA;
[Tooltip("第二个文本组件")] [SerializeField] private TMP_Text textB;
[Header("动画参数")] [Tooltip("文本在中央停留显示的时间")] [SerializeField]
private float displayDuration = 4f;
[Tooltip("向上移动和淡入淡出的动画时间")] [SerializeField]
private float animationDuration = 1f;
[Tooltip("文本向上移动的距离")] [SerializeField]
private float moveDistance = 200f;
// --- 可选: 如果你想让文字内容循环变化 ---
[Header("可选的文本内容")] [Tooltip("在这里填入你想循环显示的文字列表")] [SerializeField]
private List<string> textContents = new List<string>();
private TMP_Text[] _textElements;
private int _currentTextIndex = 0; // 当前显示在中央的文本的索引 (0 或 1)
private int _contentIndex = 0; // 当前显示内容的索引
private Vector2 _centerPosition;
private Sequence _animationSequence;
void Start()
{
Setup();
// 直接启动第一个动画过渡
AnimateTransition();
}
void OnDestroy()
{
// 安全地杀死所有相关的DoTween动画防止在场景切换或对象销毁时出错
_animationSequence?.Kill();
}
/// <summary>
/// 初始化设置
/// </summary>
private void Setup()
{
_textElements = new[] { textA, textB };
// 记录中心位置
_centerPosition = textA.rectTransform.anchoredPosition;
// 设置 textA 的初始状态
textA.rectTransform.anchoredPosition = _centerPosition;
textA.alpha = 1f;
UpdateTextContent(textA); // 设置初始文字
// 设置 textB 的初始状态 (在下方,透明)
textB.rectTransform.anchoredPosition = _centerPosition - new Vector2(0, moveDistance);
textB.alpha = 0f;
// textB 的内容将在它动画开始前更新,所以这里无需设置
}
/// <summary>
/// 执行一次完整的文本过渡动画,并在完成后自我调用以形成循环
/// </summary>
private void AnimateTransition()
{
// 确定哪个文本要移出,哪个要移入
TMP_Text textToAnimateOut = _textElements[_currentTextIndex];
TMP_Text textToAnimateIn = _textElements[(_currentTextIndex + 1) % 2];
// 创建一个新的动画序列
_animationSequence = DOTween.Sequence();
_animationSequence
.AppendInterval(displayDuration) // 1. 等待当前文本显示4秒
.AppendCallback(() => {
// 2. 在动画开始前,更新即将进入的文本的内容
UpdateTextContent(textToAnimateIn);
})
// 3. 同时执行两个文本的动画
.Append(textToAnimateOut.rectTransform.DOAnchorPosY(_centerPosition.y + moveDistance, animationDuration).SetEase(Ease.OutCubic))
.Join(textToAnimateOut.DOFade(0f, animationDuration).SetEase(Ease.OutCubic))
.Join(textToAnimateIn.rectTransform.DOAnchorPosY(_centerPosition.y, animationDuration).SetEase(Ease.OutCubic))
.Join(textToAnimateIn.DOFade(1f, animationDuration).SetEase(Ease.OutCubic))
.OnComplete(() => {
// 4. 当整个过渡动画完成时
// 将刚刚移出的文本复位到起始位置,为下一次进入做准备
textToAnimateOut.rectTransform.anchoredPosition = _centerPosition - new Vector2(0, moveDistance);
// 切换当前文本的索引,为下个循环做准备
_currentTextIndex = (_currentTextIndex + 1) % 2;
// 启动下一次动画过渡,形成循环
AnimateTransition();
});
_animationSequence.Play();
}
/// <summary>
/// 更新文本内容(如果列表不为空)
/// </summary>
private void UpdateTextContent(TMP_Text textElement)
{
if (textContents == null || textContents.Count == 0)
{
return; // 如果列表为空,则不改变文字
}
textElement.text = textContents[_contentIndex];
_contentIndex = (_contentIndex + 1) % textContents.Count; // 移动到下一个内容索引,并循环
}
}
}