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

200 lines
5.3 KiB
C#

using DG.Tweening;
using UnityEngine;
[DisallowMultipleComponent]
public class UI_PanelPopupTween : MonoBehaviour
{
[SerializeField] private RectTransform moveTarget;
[SerializeField] private CanvasGroup fadeTarget;
[SerializeField] private bool playOnEnable = true;
[SerializeField] private float enterDuration = 0.2f;
[SerializeField] private float exitDuration = 0.16f;
[SerializeField] private float fromOffsetY = 24f;
[SerializeField] private float scaleFrom = 0.96f;
[SerializeField] private Ease enterEase = Ease.OutCubic;
[SerializeField] private Ease exitEase = Ease.InCubic;
[SerializeField] private bool useUnscaledTime = true;
private Sequence enterSequence;
private bool baseCached;
private Vector2 basePos;
private Vector3 baseScale;
private void Awake()
{
AutoWire();
CacheBaseState();
}
private void OnEnable()
{
if (playOnEnable)
{
Play();
}
}
private void OnDisable()
{
KillTween();
ResetToBase();
}
public void Play()
{
AutoWire();
CacheBaseState();
if (moveTarget == null || fadeTarget == null)
{
return;
}
KillTween();
Vector2 fromPos = basePos + new Vector2(0f, -Mathf.Abs(fromOffsetY));
bool canAnimateTransform = !UI_OrderedEntryAnimator.IsLayoutSensitive(moveTarget);
if (canAnimateTransform)
{
moveTarget.anchoredPosition = fromPos;
moveTarget.localScale = baseScale * Mathf.Max(0.01f, scaleFrom);
}
fadeTarget.alpha = 0f;
fadeTarget.interactable = false;
fadeTarget.blocksRaycasts = false;
float duration = Mathf.Max(0.01f, enterDuration);
enterSequence = DOTween.Sequence().SetUpdate(useUnscaledTime);
if (canAnimateTransform)
{
enterSequence.Join(moveTarget.DOAnchorPos(basePos, duration).SetEase(enterEase));
enterSequence.Join(moveTarget.DOScale(baseScale, duration).SetEase(enterEase));
}
enterSequence.Join(fadeTarget.DOFade(1f, duration).SetEase(Ease.OutCubic));
enterSequence.OnComplete(() =>
{
fadeTarget.interactable = true;
fadeTarget.blocksRaycasts = true;
enterSequence = null;
});
enterSequence.OnKill(() =>
{
ResetToBase();
enterSequence = null;
});
}
public void PlayExitThen(System.Action onComplete)
{
AutoWire();
CacheBaseState();
if (moveTarget == null || fadeTarget == null)
{
onComplete?.Invoke();
return;
}
KillTween();
fadeTarget.interactable = false;
fadeTarget.blocksRaycasts = false;
Vector2 targetPos = basePos + new Vector2(0f, -Mathf.Abs(fromOffsetY));
Vector3 targetScale = baseScale * Mathf.Max(0.01f, scaleFrom);
float duration = Mathf.Max(0.01f, exitDuration);
bool canAnimateTransform = !UI_OrderedEntryAnimator.IsLayoutSensitive(moveTarget);
enterSequence = DOTween.Sequence().SetUpdate(useUnscaledTime);
if (canAnimateTransform)
{
enterSequence.Join(moveTarget.DOAnchorPos(targetPos, duration).SetEase(exitEase));
enterSequence.Join(moveTarget.DOScale(targetScale, duration).SetEase(exitEase));
}
enterSequence.Join(fadeTarget.DOFade(0f, duration).SetEase(Ease.InCubic));
enterSequence.OnComplete(() =>
{
enterSequence = null;
ResetToBase();
onComplete?.Invoke();
});
enterSequence.OnKill(() =>
{
ResetToBase();
enterSequence = null;
});
}
private void AutoWire()
{
if (moveTarget == null)
{
moveTarget = transform as RectTransform;
if (moveTarget == null)
{
moveTarget = GetComponentInChildren<RectTransform>(true);
}
}
if (fadeTarget == null)
{
fadeTarget = GetComponent<CanvasGroup>();
}
if (fadeTarget == null)
{
fadeTarget = gameObject.AddComponent<CanvasGroup>();
}
}
private void CacheBaseState()
{
if (moveTarget == null || baseCached)
{
return;
}
basePos = moveTarget.anchoredPosition;
baseScale = moveTarget.localScale;
baseCached = true;
}
private void ResetToBase()
{
if (moveTarget != null && baseCached)
{
if (!UI_OrderedEntryAnimator.IsLayoutSensitive(moveTarget))
{
moveTarget.anchoredPosition = basePos;
moveTarget.localScale = baseScale;
}
}
if (fadeTarget != null)
{
fadeTarget.alpha = 1f;
fadeTarget.interactable = true;
fadeTarget.blocksRaycasts = true;
}
}
private void KillTween()
{
if (enterSequence != null)
{
enterSequence.Kill();
enterSequence = null;
}
if (moveTarget != null)
{
moveTarget.DOKill();
}
if (fadeTarget != null)
{
fadeTarget.DOKill();
}
}
}