MayHeCome/Assets/三问c#/动画器/AnimationUI.cs
2024-12-18 17:55:34 +08:00

251 lines
7.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}