251 lines
7.9 KiB
C#
251 lines
7.9 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
using DG.Tweening;
|
||
using UnityEngine.UI;
|
||
|
||
// 定义一个具体的基类,所有UI动画效果继承自这个类
|
||
[System.Serializable]
|
||
public class BaseUIEffect
|
||
{
|
||
public int ListIndex; // 用于排序的索引
|
||
public virtual Tweener ApplyUIAnimation(RectTransform target, CanvasGroup canvasGroup)
|
||
{
|
||
// 在基类中实现一个默认的动画行为
|
||
Debug.Log("基类UI动画未实现");
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 定义UI动画效果类,继承自 BaseUIEffect
|
||
[System.Serializable]
|
||
public class UIAnimationEffect : BaseUIEffect
|
||
{
|
||
public enum AnimationType { Move, Rotate, Scale, Fade } // 动画类型
|
||
public AnimationType animationType; // 当前动画类型
|
||
|
||
public Vector3 targetValue; // 目标值(位移、旋转或缩放)
|
||
public float duration = 1f; // 动画持续时间
|
||
public Ease easeType = Ease.Linear; // 缓动类型
|
||
public float targetAlpha; // 用于透明度动画
|
||
|
||
// 重写 ApplyUIAnimation 方法
|
||
public override Tweener ApplyUIAnimation(RectTransform target, CanvasGroup canvasGroup)
|
||
{
|
||
Tweener tweener = null;
|
||
|
||
switch (animationType)
|
||
{
|
||
case AnimationType.Move:
|
||
tweener = target.DOAnchorPos(targetValue, duration).SetEase(easeType);
|
||
break;
|
||
case AnimationType.Rotate:
|
||
tweener = target.DORotate(targetValue, duration).SetEase(easeType);
|
||
break;
|
||
case AnimationType.Scale:
|
||
tweener = target.DOScale(targetValue, duration).SetEase(easeType);
|
||
break;
|
||
case AnimationType.Fade:
|
||
if (canvasGroup != null)
|
||
{
|
||
tweener = canvasGroup.DOFade(targetAlpha, duration).SetEase(easeType);
|
||
}
|
||
break;
|
||
}
|
||
|
||
return tweener;
|
||
}
|
||
}
|
||
|
||
// 定义抖动效果类,继承自 BaseUIEffect
|
||
[System.Serializable]
|
||
public class UIShakeEffect : BaseUIEffect
|
||
{
|
||
public enum ShakeType { Position, Rotation } // 抖动类型
|
||
public ShakeType shakeType; // 当前抖动类型
|
||
|
||
public Vector3 strength = Vector3.one; // 抖动强度
|
||
public int vibrato = 10; // 抖动次数
|
||
public float randomness = 90f; // 抖动的随机性
|
||
public float duration = 1f; // 抖动持续时间
|
||
|
||
// 重写 ApplyUIAnimation 方法,处理UI抖动效果
|
||
public override Tweener ApplyUIAnimation(RectTransform target, CanvasGroup canvasGroup)
|
||
{
|
||
Tweener tweener = null;
|
||
|
||
switch (shakeType)
|
||
{
|
||
case ShakeType.Position:
|
||
tweener = target.DOShakeAnchorPos(duration, strength, vibrato, randomness);
|
||
break;
|
||
case ShakeType.Rotation:
|
||
tweener = target.DOShakeRotation(duration, strength, vibrato, randomness);
|
||
break;
|
||
}
|
||
|
||
return tweener;
|
||
}
|
||
}
|
||
|
||
public class AnimationUI : MonoBehaviour
|
||
{
|
||
public Button button;//UI按钮
|
||
public RectTransform targetRectTransform; // UI目标对象的RectTransform
|
||
public CanvasGroup targetCanvasGroup; // UI透明度控制的CanvasGroup
|
||
|
||
public List<UIAnimationEffect> uiAnimationEffects = new List<UIAnimationEffect>(); // 存储UI动画效果
|
||
public List<UIShakeEffect> uiShakeEffects = new List<UIShakeEffect>(); // 存储UI抖动效果
|
||
public bool loopEntireSequence = false; // 是否循环整个动画序列
|
||
public LoopType sequenceLoopType = LoopType.Restart; // 整个序列的循环类型
|
||
|
||
// 动画序列缓存
|
||
private Sequence cachedAnimationSequence;
|
||
|
||
// 追踪动画列表是否需要更新
|
||
[HideInInspector]
|
||
public bool animationSequenceNeedsUpdate = true;
|
||
|
||
public int OnenableOpen;//是否一唤醒就动画
|
||
|
||
private void Awake()
|
||
{
|
||
DOTween.Init();
|
||
targetRectTransform = GetComponent<RectTransform>();
|
||
}
|
||
private void OnEnable()
|
||
{
|
||
if (OnenableOpen == 0)
|
||
{
|
||
PlayUIAnimations();
|
||
}
|
||
else if (OnenableOpen == 1)
|
||
{
|
||
|
||
if (button == null)
|
||
{
|
||
if (!TryGetComponent<Button>(out button))
|
||
{
|
||
Debug.LogWarning("未添加组件按钮");
|
||
}
|
||
else
|
||
{
|
||
button.onClick.AddListener(PlayUIAnimations);
|
||
}
|
||
}
|
||
}
|
||
else if (OnenableOpen == 2)
|
||
{
|
||
RestartAnimations();
|
||
}
|
||
}
|
||
private void OnDisable()
|
||
{
|
||
if (OnenableOpen == 2)
|
||
{
|
||
gameObject.SetActive(true);
|
||
cachedAnimationSequence.OnComplete(() =>
|
||
{
|
||
gameObject.SetActive(false);
|
||
});
|
||
PlayUIAnimations();
|
||
}
|
||
else
|
||
{
|
||
RestartAnimations();
|
||
}
|
||
}
|
||
// 更新动画序列,当动画效果更改时调用此方法
|
||
public void UpdateUIAnimationSequence()
|
||
{
|
||
// 如果已经有缓存的动画序列,先停止并销毁
|
||
if (cachedAnimationSequence != null)
|
||
{
|
||
cachedAnimationSequence.Kill();
|
||
}
|
||
// 创建新的动画序列
|
||
cachedAnimationSequence = DOTween.Sequence().SetAutoKill(false); ;
|
||
|
||
// 将两个列表合并并按 ListIndex 排序
|
||
List<BaseUIEffect> sortedEffects = new List<BaseUIEffect>();
|
||
sortedEffects.AddRange(uiAnimationEffects);
|
||
sortedEffects.AddRange(uiShakeEffects);
|
||
|
||
// 按 ListIndex 排序
|
||
sortedEffects = sortedEffects.OrderBy(effect => effect.ListIndex).ToList();
|
||
|
||
// 遍历排序后的效果列表,按顺序生成动画
|
||
// 遍历排序后的效果列表,按顺序生成动画
|
||
foreach (var effect in sortedEffects)
|
||
{
|
||
if (effect is UIAnimationEffect uiAnimationEffect)
|
||
{
|
||
// 移除这一行,避免强制将所有动画类型变成 Fade
|
||
// uiAnimationEffect.animationType = UIAnimationEffect.AnimationType.Fade;
|
||
|
||
// 检查 CanvasGroup 是否存在(只针对 Fade 动画类型)
|
||
if (uiAnimationEffect.animationType == UIAnimationEffect.AnimationType.Fade && !TryGetComponent<CanvasGroup>(out targetCanvasGroup))
|
||
{
|
||
Debug.LogWarning("没有添加组件CanvasGroup");
|
||
}
|
||
}
|
||
|
||
// 应用动画
|
||
Tweener tweener = effect.ApplyUIAnimation(targetRectTransform, targetCanvasGroup);
|
||
if (tweener != null)
|
||
{
|
||
cachedAnimationSequence.Append(tweener);
|
||
}
|
||
}
|
||
|
||
|
||
// 如果需要让整个序列循环
|
||
if (loopEntireSequence)
|
||
{
|
||
cachedAnimationSequence.SetLoops(-1, sequenceLoopType);
|
||
}
|
||
|
||
// 标记动画序列已经更新
|
||
animationSequenceNeedsUpdate = false;
|
||
}
|
||
|
||
// 播放动画,如果动画序列需要更新则先更新
|
||
public void PlayUIAnimations()
|
||
{
|
||
if (animationSequenceNeedsUpdate)
|
||
{
|
||
UpdateUIAnimationSequence();
|
||
}
|
||
|
||
if (cachedAnimationSequence != null)
|
||
{
|
||
cachedAnimationSequence.Play();
|
||
}
|
||
}
|
||
|
||
// 停止动画
|
||
public void StopUIAnimations()
|
||
{
|
||
if (cachedAnimationSequence != null)
|
||
{
|
||
cachedAnimationSequence.Kill();
|
||
animationSequenceNeedsUpdate = true;
|
||
}
|
||
}
|
||
//复位
|
||
public void RestartAnimations()
|
||
{
|
||
if (cachedAnimationSequence != null)
|
||
{
|
||
cachedAnimationSequence.Restart();
|
||
cachedAnimationSequence.Pause();
|
||
}
|
||
}
|
||
// 当Inspector面板中的值发生更改时调用
|
||
private void OnValidate()
|
||
{
|
||
// Debug.Log("UI动画更新");
|
||
animationSequenceNeedsUpdate = true;
|
||
}
|
||
} |