改动与优化

This commit is contained in:
FloatGaming
2026-07-20 22:19:25 +08:00
parent 0a0872c4f4
commit b5d1cdcbc5
83 changed files with 2475 additions and 276 deletions
+185 -8
View File
@@ -6,6 +6,82 @@ using UnityEngine.UI;
public static class UI_OrderedEntryAnimator
{
public static Sequence PlaySingle(
GameObject target,
int orderIndex = 0,
float duration = 0.22f,
float stagger = 0.018f,
float fromYOffset = -18f,
float fromScale = 0.96f,
bool useUnscaledTime = true,
bool forceFadeOnly = false)
{
if (target == null || !target.activeInHierarchy) return null;
RectTransform rect = target.transform as RectTransform;
if (rect == null) rect = target.GetComponent<RectTransform>();
if (rect == null) return null;
DOTween.Kill(target);
CanvasGroup group = target.GetComponent<CanvasGroup>();
if (group == null) group = target.AddComponent<CanvasGroup>();
rect.DOKill();
group.DOKill();
float safeDuration = Mathf.Max(0.01f, duration);
float delay = Mathf.Max(0f, stagger) * Mathf.Max(0, orderIndex);
Vector2 basePos = rect.anchoredPosition;
Vector3 baseScale = rect.localScale;
float targetAlpha = group.alpha <= 0f ? 1f : group.alpha;
bool layoutControlled = forceFadeOnly || IsLayoutSensitive(rect);
if (!layoutControlled)
{
rect.anchoredPosition = basePos + new Vector2(0f, fromYOffset);
rect.localScale = baseScale * Mathf.Max(0.01f, fromScale);
}
group.alpha = 0f;
Sequence sequence = DOTween.Sequence().SetUpdate(useUnscaledTime).SetTarget(target);
sequence.SetDelay(delay);
if (!layoutControlled)
{
sequence.Join(rect.DOAnchorPos(basePos, safeDuration).SetEase(Ease.OutCubic).SetUpdate(useUnscaledTime));
sequence.Join(rect.DOScale(baseScale, safeDuration).SetEase(Ease.OutBack).SetUpdate(useUnscaledTime));
}
sequence.Join(group.DOFade(targetAlpha, safeDuration).SetEase(Ease.OutCubic).SetUpdate(useUnscaledTime));
sequence.OnKill(() => Restore(rect, group, basePos, baseScale, targetAlpha, !layoutControlled));
sequence.OnComplete(() => Restore(rect, group, basePos, baseScale, targetAlpha, !layoutControlled));
return sequence;
}
public static Sequence PlayRefresh(
GameObject target,
float duration = 0.18f,
float fromYOffset = -10f,
float fromScale = 0.985f,
bool useUnscaledTime = true)
{
return PlaySingle(target, 0, duration, 0f, fromYOffset, fromScale, useUnscaledTime);
}
public static Sequence PlayFadeOnly(
GameObject target,
int orderIndex = 0,
float duration = 0.18f,
float stagger = 0.012f,
bool useUnscaledTime = true)
{
return PlaySingle(target, orderIndex, duration, stagger, 0f, 1f, useUnscaledTime, true);
}
public static Sequence PlayRefresh(Component target, float duration = 0.18f, float fromYOffset = -10f, float fromScale = 0.985f, bool useUnscaledTime = true)
{
return target != null ? PlayRefresh(target.gameObject, duration, fromYOffset, fromScale, useUnscaledTime) : null;
}
public static Sequence Play(
Transform root,
float itemDuration,
@@ -24,6 +100,7 @@ public static class UI_OrderedEntryAnimator
float duration = Mathf.Max(0.01f, itemDuration);
float stagger = Mathf.Max(0f, itemStagger);
Sequence sequence = DOTween.Sequence().SetUpdate(useUnscaledTime);
List<AnimState> states = new List<AnimState>(targets.Count);
for (int i = 0; i < targets.Count; i++)
{
@@ -37,19 +114,111 @@ public static class UI_OrderedEntryAnimator
group.DOKill();
Vector2 basePos = rt.anchoredPosition;
Vector3 baseScale = rt.localScale;
float baseAlpha = group.alpha <= 0f ? 1f : group.alpha;
bool layoutControlled = IsLayoutSensitive(rt);
states.Add(new AnimState(rt, group, basePos, baseScale, baseAlpha, !layoutControlled));
rt.anchoredPosition = basePos + fromOffset;
if (!layoutControlled)
{
rt.anchoredPosition = basePos + fromOffset;
}
group.alpha = 0f;
float startAt = i * stagger;
sequence.Insert(startAt, rt.DOAnchorPos(basePos, duration).SetEase(Ease.OutCubic).SetUpdate(useUnscaledTime));
if (!layoutControlled)
{
sequence.Insert(startAt, rt.DOAnchorPos(basePos, duration).SetEase(Ease.OutCubic).SetUpdate(useUnscaledTime));
}
sequence.Insert(startAt, group.DOFade(baseAlpha, duration).SetEase(Ease.OutCubic).SetUpdate(useUnscaledTime));
}
sequence.OnKill(() => RestoreAll(states));
sequence.OnComplete(() => RestoreAll(states));
return sequence;
}
private struct AnimState
{
public RectTransform Rect;
public CanvasGroup Group;
public Vector2 AnchoredPosition;
public Vector3 Scale;
public float Alpha;
public bool RestoreTransform;
public AnimState(RectTransform rect, CanvasGroup group, Vector2 anchoredPosition, Vector3 scale, float alpha, bool restoreTransform)
{
Rect = rect;
Group = group;
AnchoredPosition = anchoredPosition;
Scale = scale;
Alpha = alpha;
RestoreTransform = restoreTransform;
}
}
private static void RestoreAll(List<AnimState> states)
{
if (states == null)
{
return;
}
for (int i = 0; i < states.Count; i++)
{
AnimState state = states[i];
Restore(state.Rect, state.Group, state.AnchoredPosition, state.Scale, state.Alpha, state.RestoreTransform);
}
}
private static void Restore(RectTransform rect, CanvasGroup group, Vector2 anchoredPosition, Vector3 scale, float alpha, bool restoreTransform)
{
if (restoreTransform && rect != null)
{
rect.anchoredPosition = anchoredPosition;
rect.localScale = scale;
}
if (group != null)
{
group.alpha = alpha;
}
}
public static bool IsLayoutSensitive(RectTransform rect)
{
if (rect == null)
{
return false;
}
if (rect.GetComponent<LayoutGroup>() != null || rect.GetComponent<ContentSizeFitter>() != null)
{
return true;
}
Transform current = rect;
while (current != null && current.parent != null)
{
Transform parent = current.parent;
if (parent.GetComponent<LayoutGroup>() != null)
{
return true;
}
RectTransform currentRect = current as RectTransform;
if (currentRect != null && currentRect.GetComponent<LayoutElement>() != null && parent.GetComponent<ContentSizeFitter>() != null)
{
return true;
}
current = parent;
}
return false;
}
public static Sequence PlayKeyDownFlash(
Transform keyDownRoot,
bool useUnscaledTime,
@@ -122,15 +291,23 @@ public static class UI_OrderedEntryAnimator
{
Transform child = parent.GetChild(i);
if (child == null) continue;
stack.Push(child);
RectTransform rt = child as RectTransform;
if (rt == null || !child.gameObject.activeInHierarchy) continue;
if (includePredicate != null && !includePredicate(rt)) continue;
if (!IsPanelLike(child)) continue;
if (!seen.Add(rt)) continue;
bool canConsider = rt != null && child.gameObject.activeInHierarchy;
bool included = false;
if (canConsider
&& (includePredicate == null || includePredicate(rt))
&& IsPanelLike(child)
&& seen.Add(rt))
{
list.Add(rt);
included = true;
}
list.Add(rt);
if (!included || !IsLayoutSensitive(rt))
{
stack.Push(child);
}
}
}