Files
bansonic_beta_main/Assets/scripts/UI/Panel/dontdestroyonload/UI_PanelExitUtility.cs
T
2026-07-20 22:19:25 +08:00

126 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
public static class UI_PanelExitUtility
{
private const float FallbackExitDuration = 0.16f;
private const float FallbackExitScale = 0.96f;
private static readonly HashSet<GameObject> ExitingPanels = new HashSet<GameObject>();
public static bool PlayExitThen(GameObject panel, Action onComplete)
{
if (panel == null || !panel.activeInHierarchy)
{
onComplete?.Invoke();
return false;
}
if (ExitingPanels.Contains(panel))
{
return true;
}
ExitingPanels.Add(panel);
bool completed = false;
Action safeComplete = () =>
{
if (completed)
{
return;
}
completed = true;
ExitingPanels.Remove(panel);
onComplete?.Invoke();
};
DOVirtual.DelayedCall(2.5f, () => safeComplete(), true);
UI_SettingsPanelEnterAnim settingsAnim = panel.GetComponent<UI_SettingsPanelEnterAnim>();
if (settingsAnim != null && settingsAnim.enabled)
{
settingsAnim.PlayExitThen(safeComplete);
return true;
}
UI_PanelPopupTween popupTween = panel.GetComponent<UI_PanelPopupTween>();
if (popupTween != null && popupTween.enabled)
{
popupTween.PlayExitThen(safeComplete);
return true;
}
return PlayFallbackExitThen(panel, safeComplete);
}
private static bool PlayFallbackExitThen(GameObject panel, Action onComplete)
{
RectTransform rect = panel != null ? panel.transform as RectTransform : null;
CanvasGroup group = panel != null ? panel.GetComponent<CanvasGroup>() : null;
if (rect == null && group == null)
{
onComplete?.Invoke();
return false;
}
if (group == null)
{
group = panel.AddComponent<CanvasGroup>();
}
Vector3 baseScale = rect != null ? rect.localScale : Vector3.one;
float baseAlpha = group.alpha;
float duration = Mathf.Max(0.01f, FallbackExitDuration);
bool canScale = rect == null || !UI_OrderedEntryAnimator.IsLayoutSensitive(rect);
if (rect != null)
{
rect.DOKill();
}
group.DOKill();
group.interactable = false;
group.blocksRaycasts = false;
Sequence seq = DOTween.Sequence().SetUpdate(true);
if (rect != null && canScale)
{
seq.Join(rect.DOScale(baseScale * FallbackExitScale, duration).SetEase(Ease.InCubic));
}
seq.Join(group.DOFade(0f, duration).SetEase(Ease.InCubic));
bool restored = false;
Action restore = () =>
{
if (restored)
{
return;
}
restored = true;
if (rect != null && canScale)
{
rect.localScale = baseScale;
}
if (group != null)
{
group.alpha = baseAlpha;
group.interactable = true;
group.blocksRaycasts = true;
}
};
seq.OnComplete(() =>
{
restore();
onComplete?.Invoke();
});
seq.OnKill(() => restore());
return true;
}
}