改动与优化

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
@@ -41,6 +41,20 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
[SerializeField] private bool allyUsePseudoYTurnForUI = true;
[SerializeField] private float allyPseudoStartScaleX = 0.68f;
[Header("Additional HUD")]
[SerializeField] private bool animateAdditionalHudRoots = true;
[SerializeField] private float additionalHudStartYOffset = -35f;
[SerializeField] private float additionalHudMoveDuration = 0.24f;
[SerializeField] private float additionalHudStagger = 0.035f;
[SerializeField]
private string[] additionalHudRootNames =
{
"healthSys",
"manaSys",
"progressLineBottom",
"progressLineColor"
};
private bool playedOnce;
private bool refsCached;
private bool preStartPrepared;
@@ -64,12 +78,15 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
private readonly List<Transform> gameObjectRects = new List<Transform>();
private readonly List<Transform> colorRects = new List<Transform>();
private readonly List<Transform> allies = new List<Transform>();
private readonly List<Transform> additionalHudRoots = new List<Transform>();
private readonly List<Transform> explicitKeyDownRects = new List<Transform>(5);
private readonly Dictionary<Graphic, float> baseGraphicAlpha = new Dictionary<Graphic, float>();
private readonly Dictionary<SpriteRenderer, float> baseSpriteAlpha = new Dictionary<SpriteRenderer, float>();
private readonly Dictionary<CanvasGroup, float> baseCanvasGroupAlpha = new Dictionary<CanvasGroup, float>();
private readonly Dictionary<Transform, Vector3> baseLocalScale = new Dictionary<Transform, Vector3>();
private readonly Dictionary<Transform, Vector3> baseLocalPosition = new Dictionary<Transform, Vector3>();
private readonly Dictionary<Transform, float> rootCanvasBaseAlpha = new Dictionary<Transform, float>();
private readonly Dictionary<Transform, CanvasGroup> rootCanvasGroups = new Dictionary<Transform, CanvasGroup>();
private void Awake()
@@ -85,6 +102,17 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
StartCoroutine(PreparePreStartStateNextFrame());
}
private void OnDisable()
{
if (playRoutine == null) return;
// If the object is disabled during the intro, keep HUD from being stranded mid-animation.
StopCoroutine(playRoutine);
ApplyIntroFinalState();
playedOnce = true;
playRoutine = null;
}
private void LateUpdate()
{
if (!keepHiddenBeforeStart) return;
@@ -206,6 +234,12 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
}
allies.Sort((a, b) => a.name.CompareTo(b.name));
additionalHudRoots.Clear();
if (animateAdditionalHudRoots)
{
additionalHudRoots.AddRange(CollectAdditionalHudRoots());
}
refsCached = true;
}
@@ -265,6 +299,14 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
if (totalEnemyTop != null) SetScaleY(totalEnemyTop, 0f);
if (totalEnemyFade != null) SetScaleY(totalEnemyFade, 0f);
for (int i = 0; i < additionalHudRoots.Count; i++)
{
Transform hud = additionalHudRoots[i];
if (hud == null) continue;
SetRootCanvasAlphaNormalized(hud, 0f);
SetLocalPosition(hud, GetBaseLocalPosition(hud) + new Vector3(0f, additionalHudStartYOffset, 0f));
}
preStartPrepared = true;
}
@@ -306,16 +348,74 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
Coroutine enemyStep = StartCoroutine(PlayEnemyStep(enemyRoot, enemyListBall, enemyStatics, enemySpineSystem, totalEnemyTop, totalEnemyFade));
Coroutine progressStep = StartCoroutine(FlashIn(progressLine, flashTimes, flashDuration, true));
Coroutine alliesStep = StartCoroutine(PlayAlliesAndHudStep(allies, score, pause));
Coroutine additionalHudStep = StartCoroutine(PlayAdditionalHudStep(additionalHudRoots));
if (colorStep != null) yield return colorStep;
if (enemyStep != null) yield return enemyStep;
if (progressStep != null) yield return progressStep;
if (alliesStep != null) yield return alliesStep;
if (additionalHudStep != null) yield return additionalHudStep;
ApplyIntroFinalState();
playedOnce = true;
playRoutine = null;
}
private void ApplyIntroFinalState()
{
if (bgReplace != null) SetAlphaNormalized(bgReplace, 1f, true);
if (colorLineStatic != null) SetAlphaNormalized(colorLineStatic, 1f, true);
if (enemyRoot != null) SetAlphaNormalized(enemyRoot, 1f, true);
if (enemyListBall != null) SetAlphaNormalized(enemyListBall, 1f, true);
if (enemyStatics != null) SetAlphaNormalized(enemyStatics, 1f, true);
if (enemySpineSystem != null) enemySpineSystem.gameObject.SetActive(true);
if (progressLine != null) SetAlphaNormalized(progressLine, 1f, true);
if (score != null) SetAlphaNormalized(score, 1f, true);
if (pause != null) SetAlphaNormalized(pause, 1f, true);
for (int i = 0; i < colorRects.Count; i++)
{
if (colorRects[i] != null) SetAlphaNormalized(colorRects[i], 1f, true);
}
for (int i = 0; i < keyDownRects.Count; i++)
{
Transform t = keyDownRects[i];
if (t == null) continue;
SetAlphaNormalized(t, 1f, true);
SetLocalY(t, keyDownTargetY);
SetLocalRotY(t, keyDownTargetRotY);
}
for (int i = 0; i < gameObjectRects.Count; i++)
{
Transform t = gameObjectRects[i];
if (t == null) continue;
SetAlphaNormalized(t, 1f, true);
SetLocalY(t, gameObjectTargetY);
}
for (int i = 0; i < allies.Count; i++)
{
Transform ally = allies[i];
if (ally == null) continue;
SetRootCanvasAlpha(ally, 1f);
SetPseudoTurnScaleX(ally, 1f);
SetLocalRotY(ally, allyTargetRotY);
}
if (totalEnemyTop != null) SetScaleY(totalEnemyTop, 1f);
if (totalEnemyFade != null) SetScaleY(totalEnemyFade, 1f);
for (int i = 0; i < additionalHudRoots.Count; i++)
{
Transform hud = additionalHudRoots[i];
if (hud == null) continue;
SetRootCanvasAlphaNormalized(hud, 1f);
SetLocalPosition(hud, GetBaseLocalPosition(hud));
}
}
private IEnumerator PlayEnemyStep(
Transform enemyRootTr,
Transform enemyListBallTr,
@@ -379,6 +479,48 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
yield return StartCoroutine(FlashIn(pauseTr, flashTimes, hudFlashDuration, true));
}
private IEnumerator PlayAdditionalHudStep(List<Transform> hudList)
{
if (hudList == null || hudList.Count == 0) yield break;
for (int i = 0; i < hudList.Count; i++)
{
Transform hud = hudList[i];
if (hud == null) continue;
StartCoroutine(AnimateAdditionalHudRoot(hud));
if (i < hudList.Count - 1 && additionalHudStagger > 0f)
yield return WaitRealtime(additionalHudStagger);
}
yield return WaitRealtime(additionalHudMoveDuration);
}
private IEnumerator AnimateAdditionalHudRoot(Transform hud)
{
if (hud == null) yield break;
Vector3 basePos = GetBaseLocalPosition(hud);
Vector3 from = basePos + new Vector3(0f, additionalHudStartYOffset, 0f);
float elapsed = 0f;
float dur = Mathf.Max(0.01f, additionalHudMoveDuration);
SetLocalPosition(hud, from);
SetRootCanvasAlphaNormalized(hud, 0f);
while (elapsed < dur)
{
elapsed += Time.unscaledDeltaTime;
float k = EaseOutCubic(Mathf.Clamp01(elapsed / dur));
SetLocalPosition(hud, Vector3.LerpUnclamped(from, basePos, k));
SetRootCanvasAlphaNormalized(hud, k);
yield return null;
}
SetLocalPosition(hud, basePos);
SetRootCanvasAlphaNormalized(hud, 1f);
}
private IEnumerator FlashInSequence(List<Transform> list, int flashes, float duration, float stagger)
{
if (list == null || list.Count == 0) yield break;
@@ -624,6 +766,23 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
return s;
}
private Vector3 GetBaseLocalPosition(Transform t)
{
if (t == null) return Vector3.zero;
if (!baseLocalPosition.TryGetValue(t, out Vector3 p))
{
p = t.localPosition;
baseLocalPosition[t] = p;
}
return p;
}
private static void SetLocalPosition(Transform t, Vector3 localPosition)
{
if (t == null) return;
t.localPosition = localPosition;
}
private static void SetScaleY(Transform t, float y)
{
if (t == null) return;
@@ -748,6 +907,21 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
cg.alpha = n;
}
private void SetRootCanvasAlphaNormalized(Transform root, float normalized)
{
if (root == null) return;
CanvasGroup cg = GetOrAddRootCanvasGroup(root);
if (cg == null) return;
if (!rootCanvasBaseAlpha.TryGetValue(root, out float baseAlpha))
{
baseAlpha = cg.alpha;
rootCanvasBaseAlpha[root] = baseAlpha;
}
cg.alpha = baseAlpha * Mathf.Clamp01(normalized);
}
private IEnumerator FlashInCanvasGroup(Transform root, int flashes, float duration)
{
if (root == null) yield break;
@@ -812,6 +986,78 @@ public class GameplayTrackStartIntroAnimator : MonoBehaviour
return list;
}
private List<Transform> CollectAdditionalHudRoots()
{
List<Transform> list = new List<Transform>();
if (additionalHudRootNames == null || additionalHudRootNames.Length == 0) return list;
HashSet<int> seen = new HashSet<int>();
Transform[] all = GetAllSceneTransforms();
for (int i = 0; i < all.Length; i++)
{
Transform t = all[i];
if (t == null || string.IsNullOrEmpty(t.name)) continue;
if (!IsAdditionalHudName(t.name)) continue;
if (IsAlreadyHandledByMainIntro(t)) continue;
if (!seen.Add(t.GetInstanceID())) continue;
list.Add(t);
}
list.Sort((a, b) =>
{
int ay = a != null ? Mathf.RoundToInt(-a.position.y * 1000f) : 0;
int by = b != null ? Mathf.RoundToInt(-b.position.y * 1000f) : 0;
int yCmp = ay.CompareTo(by);
if (yCmp != 0) return yCmp;
return (a != null ? a.GetSiblingIndex() : 0).CompareTo(b != null ? b.GetSiblingIndex() : 0);
});
return list;
}
private bool IsAdditionalHudName(string candidateName)
{
for (int i = 0; i < additionalHudRootNames.Length; i++)
{
string targetName = additionalHudRootNames[i];
if (string.IsNullOrEmpty(targetName)) continue;
if (string.Equals(candidateName, targetName, System.StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}
private bool IsAlreadyHandledByMainIntro(Transform t)
{
if (t == null) return true;
if (IsSelfOrChildOf(t, keyDown) ||
IsSelfOrChildOf(t, colorLineStatic) ||
IsSelfOrChildOf(t, enemyRoot) ||
IsSelfOrChildOf(t, progressLine) ||
IsSelfOrChildOf(t, score) ||
IsSelfOrChildOf(t, pause) ||
IsSelfOrChildOf(t, bgReplace))
return true;
for (int i = 0; i < keyDownRects.Count; i++)
if (IsSelfOrChildOf(t, keyDownRects[i])) return true;
for (int i = 0; i < gameObjectRects.Count; i++)
if (IsSelfOrChildOf(t, gameObjectRects[i])) return true;
for (int i = 0; i < colorRects.Count; i++)
if (IsSelfOrChildOf(t, colorRects[i])) return true;
for (int i = 0; i < allies.Count; i++)
if (IsSelfOrChildOf(t, allies[i])) return true;
return false;
}
private static bool IsSelfOrChildOf(Transform candidate, Transform root)
{
if (candidate == null || root == null) return false;
return candidate == root || candidate.IsChildOf(root);
}
private List<Transform> CollectGameObjectSdw3Excluding(Transform keyDownRoot)
{
List<Transform> list = new List<Transform>();