Files
zeling_v2/Assets/_Game/Scripts/UI/Utility/UITween.cs
2026-05-25 13:21:41 +08:00

132 lines
5.2 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.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace BaseGames.UI
{
/// <summary>
/// UI 协程补间静态库。
///
/// 设计动机:消除 <see cref="BossHPBar"/>、<see cref="ToastNotification"/>、
/// <see cref="FloatingDamageText"/> 等组件中重复出现的 Lerp + WaitForEndOfFrame 样板,
/// 集中维护时间步与回调约定。所有协程默认使用 <see cref="Time.unscaledDeltaTime"/>
/// 以便 UI 动画在游戏暂停(<see cref="Time.timeScale"/> = 0时仍能播放。
///
/// 性能特征:
/// · 无堆分配(除协程对象本身);
/// · 提前返回保护无效目标;
/// · <paramref name="duration"/> &lt;= 0 时立即吸附到终态并退出(一帧 yield 用于保持
/// 与正常协程一致的栈语义)。
/// </summary>
public static class UITween
{
// ── 位置 ─────────────────────────────────────────────────────────────
/// <summary>将 RectTransform 的 anchoredPosition 平滑过渡到目标值。</summary>
public static IEnumerator MoveAnchored(RectTransform rect,
Vector2 target,
float duration,
bool unscaled = true)
{
if (rect == null) yield break;
if (duration <= 0f)
{
rect.anchoredPosition = target;
yield break;
}
Vector2 start = rect.anchoredPosition;
float t = 0f;
while (t < duration)
{
rect.anchoredPosition = Vector2.Lerp(start, target, t / duration);
t += unscaled ? Time.unscaledDeltaTime : Time.deltaTime;
yield return null;
}
rect.anchoredPosition = target;
}
// ── 透明度 ───────────────────────────────────────────────────────────
/// <summary>将 CanvasGroup.alpha 平滑过渡到目标值。</summary>
public static IEnumerator FadeCanvasGroup(CanvasGroup cg,
float target,
float duration,
bool unscaled = true)
{
if (cg == null) yield break;
if (duration <= 0f)
{
cg.alpha = target;
yield break;
}
float start = cg.alpha;
float t = 0f;
while (t < duration)
{
cg.alpha = Mathf.Lerp(start, target, t / duration);
t += unscaled ? Time.unscaledDeltaTime : Time.deltaTime;
yield return null;
}
cg.alpha = target;
}
/// <summary>将 GraphicImage / TMP_Text 等)的颜色 Alpha 通道平滑过渡到目标值。</summary>
public static IEnumerator FadeGraphic(Graphic graphic,
float targetAlpha,
float duration,
bool unscaled = true)
{
if (graphic == null) yield break;
if (duration <= 0f)
{
var c = graphic.color;
c.a = targetAlpha;
graphic.color = c;
yield break;
}
float startAlpha = graphic.color.a;
float t = 0f;
while (t < duration)
{
var c = graphic.color;
c.a = Mathf.Lerp(startAlpha, targetAlpha, t / duration);
graphic.color = c;
t += unscaled ? Time.unscaledDeltaTime : Time.deltaTime;
yield return null;
}
var fc = graphic.color;
fc.a = targetAlpha;
graphic.color = fc;
}
// ── 缩放 ─────────────────────────────────────────────────────────────
/// <summary>将 Transform 的 localScale 等比平滑过渡到目标值。</summary>
public static IEnumerator Scale(Transform tr,
Vector3 target,
float duration,
bool unscaled = true)
{
if (tr == null) yield break;
if (duration <= 0f)
{
tr.localScale = target;
yield break;
}
Vector3 start = tr.localScale;
float t = 0f;
while (t < duration)
{
tr.localScale = Vector3.Lerp(start, target, t / duration);
t += unscaled ? Time.unscaledDeltaTime : Time.deltaTime;
yield return null;
}
tr.localScale = target;
}
}
}