update
This commit is contained in:
122
Assets/Scripts/UI/Elements/TextCatapult.cs
Normal file
122
Assets/Scripts/UI/Elements/TextCatapult.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
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; // 移动到下一个内容索引,并循环
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user