fix 5873 【抽卡】点击卡池页签时有几率报错

main
SunChengyong 2026-05-27 12:56:26 +08:00
parent 1f4f23a998
commit 72f565d82c
1 changed files with 13 additions and 10 deletions

View File

@ -545,7 +545,7 @@ namespace Framework.UI.Pictorial
if (hasExitAnim)
{
Debug.Log("[画报系统] 播放旧画报退出动画");
await PlayExitAnimAsync(oldAnimData);
await PlayExitAnimAsync(oldAnimData, token);
if (token.IsCancellationRequested)
{
Debug.Log("[画报系统] 构建已被新请求取消(退出动画后)");
@ -734,7 +734,7 @@ namespace Framework.UI.Pictorial
if (hasEnterAnim || hasCustomAnim)
{
Debug.Log("[画报系统] 播放新画报进入动画");
await PlayEnterAnimAsync(animData, bgImage);
await PlayEnterAnimAsync(animData, bgImage, token);
}
}
}
@ -746,7 +746,7 @@ namespace Framework.UI.Pictorial
/// 进入动画:元素从(实际位置 + offset)移动回实际位置alpha 从 alphaStart 到 alphaEnd
/// 各元素独立 duration + delay并行播放等待所有元素完成
/// </summary>
public async UniTask PlayEnterAnimAsync(PictorialAnimData animData, Image bgImageOverride = null)
public async UniTask PlayEnterAnimAsync(PictorialAnimData animData, Image bgImageOverride = null, System.Threading.CancellationToken cancellationToken = default)
{
if (animData == null) return;
@ -761,7 +761,7 @@ namespace Framework.UI.Pictorial
if (targets.Count == 0) return;
await RunAnimTweenParallel(targets, isEnter: true);
await RunAnimTweenParallel(targets, isEnter: true, cancellationToken);
}
/// <summary>
@ -769,7 +769,7 @@ namespace Framework.UI.Pictorial
/// 退出动画:元素从实际位置移动到(实际位置 + offset)alpha 从 alphaStart 到 alphaEnd
/// 各元素独立 duration + delay并行播放等待所有元素完成
/// </summary>
public async UniTask PlayExitAnimAsync(PictorialAnimData animData)
public async UniTask PlayExitAnimAsync(PictorialAnimData animData, System.Threading.CancellationToken cancellationToken = default)
{
if (animData == null) return;
@ -789,7 +789,7 @@ namespace Framework.UI.Pictorial
if (targets.Count == 0) return;
await RunAnimTweenParallel(targets, isEnter: false);
await RunAnimTweenParallel(targets, isEnter: false, cancellationToken);
}
/// <summary>
@ -947,13 +947,14 @@ namespace Framework.UI.Pictorial
/// isEnter=true : 从 (basePos + offset, alphaStart) 延迟后运动到 (basePos, alphaEnd)
/// isEnter=false: 从 (basePos, alphaStart) 延迟后运动到 (basePos + offset, alphaEnd)
/// </summary>
private async UniTask RunAnimTweenParallel(List<AnimTarget> targets, bool isEnter)
private async UniTask RunAnimTweenParallel(List<AnimTarget> targets, bool isEnter, System.Threading.CancellationToken cancellationToken = default)
{
if (targets.Count == 0) return;
// 先将所有目标设置为延迟前的初始可见状态(延迟期间保持在起始位置+起始alpha
foreach (var t in targets)
{
if (cancellationToken.IsCancellationRequested) return;
if (t.rectTransform == null) continue;
t.rectTransform.anchoredPosition3D = isEnter ? (t.basePosition + t.animData.offset) : t.basePosition;
@ -989,14 +990,14 @@ namespace Framework.UI.Pictorial
}
// 并行启动每个目标的独立动画任务,整体 WhenAll 等待全部完成
var tasks = targets.Select(t => RunSingleAnimTween(t, isEnter)).ToArray();
var tasks = targets.Select(t => RunSingleAnimTween(t, isEnter, cancellationToken)).ToArray();
await UniTask.WhenAll(tasks);
}
/// <summary>
/// 单个动画目标的补间delay 秒等待后再播放 duration 秒动画)
/// </summary>
private async UniTask RunSingleAnimTween(AnimTarget t, bool isEnter)
private async UniTask RunSingleAnimTween(AnimTarget t, bool isEnter, System.Threading.CancellationToken cancellationToken = default)
{
if (t.rectTransform == null)
{
@ -1018,6 +1019,7 @@ namespace Framework.UI.Pictorial
{
await UniTask.Yield();
waited += Time.unscaledDeltaTime;
if (cancellationToken.IsCancellationRequested) return;
// 延迟期间 rectTransform 可能已销毁
if (t.rectTransform == null)
{
@ -1049,6 +1051,7 @@ namespace Framework.UI.Pictorial
{
await UniTask.Yield();
elapsed += Time.unscaledDeltaTime;
if (cancellationToken.IsCancellationRequested) return;
if (t.rectTransform == null) return;
float rawT = Mathf.Clamp01(elapsed / duration);
@ -1064,7 +1067,7 @@ namespace Framework.UI.Pictorial
if (t.image != null)
{
SetImageAlpha(t.image, currentAlpha);
// 如果这是画报元素,同步其 ButtonMagnifiers 的 alpha如果未配置独立动画
if (t.itemIndex >= 0 && t.itemIndex < pictorialData.items.Count)
{