MayHeCome/Assets/三问c#/动画器/AnimationUI.cs

251 lines
7.9 KiB
C#
Raw Normal View History

2024-12-18 09:55:34 +00:00
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;
}
}