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

206 lines
6.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq; // 用于排序
using UnityEngine;
using DG.Tweening;
// 定义一个具体的基类,所有动画效果继承自这个类
[System.Serializable]
public class BaseEffect
{
public int ListIndex; // 用于排序的索引
public virtual Tweener ApplyAnimation(Transform target)
{
// 在基类中实现一个默认的动画行为
Debug.Log("基类动画未实现");
return null;
}
}
// 定义常规的动画效果类,继承自 BaseEffect
[System.Serializable]
public class AnimationEffect : BaseEffect
{
public enum AnimationType { Move, Rotate, Scale } // 动画类型
public AnimationType animationType; // 当前动画类型
public Vector3 targetValue; // 目标值(位移、旋转或缩放)
public float duration = 1; // 动画持续时间
public Ease easeType = Ease.Linear; // 缓动类型
// 重写 ApplyAnimation 方法
public override Tweener ApplyAnimation(Transform target)
{
Tweener tweener = null;
switch (animationType)
{
case AnimationType.Move:
tweener = target.DOMove(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;
}
return tweener;
}
}
// 定义抖动效果类,继承自 BaseEffect
[System.Serializable]
public class ShakeEffect : BaseEffect
{
public enum ShakeType { Position, Rotation } // 抖动类型
public ShakeType shakeType; // 当前抖动类型
public Vector3 strength = Vector3.one; // 抖动强度
public int vibrato = 10; // 抖动次数
public float randomness = 90f; // 抖动的随机性
public float duration = 1; // 抖动持续时间
// 重写 ApplyAnimation 方法,处理抖动效果
public override Tweener ApplyAnimation(Transform target)
{
Tweener tweener = null;
switch (shakeType)
{
case ShakeType.Position:
tweener = target.DOShakePosition(duration, strength, vibrato, randomness);
break;
case ShakeType.Rotation:
tweener = target.DOShakeRotation(duration, strength, vibrato, randomness);
break;
}
return tweener;
}
}
public class DoweenAnimator : MonoBehaviour
{
public List<AnimationEffect> animationEffects = new List<AnimationEffect>(); // 存储动画效果
public List<ShakeEffect> shakeEffects = new List<ShakeEffect>(); // 存储抖动效果
public bool loopEntireSequence = false; // 是否循环整个动画序列
public LoopType sequenceLoopType = LoopType.Restart; // 整个序列的循环类型
// 动画序列缓存
private Sequence cachedAnimationSequence;
// 追踪动画列表是否需要更新
[HideInInspector]
public bool animationSequenceNeedsUpdate = true;
public int OnenableOpen;//是否一唤醒就动画
private bool isInitialized = false;
private void Awake()
{
isInitialized = true; // 标记脚本初始化完成
}
private void OnEnable()
{
if (OnenableOpen == 1)
{
PlayAnimations();
}
}
private void OnDisable()
{
RestartAnimations();
}
// 更新动画序列,当动画效果更改时调用此方法
public void UpdateAnimationSequence()
{
Debug.Log("已经更新");
// 如果已经有缓存的动画序列,先停止并销毁
if (cachedAnimationSequence != null)
{
cachedAnimationSequence.Kill();
}
// 创建新的动画序列
cachedAnimationSequence = DOTween.Sequence().SetAutoKill(false);
// 将两个列表合并并按 ListIndex 排序
List<BaseEffect> sortedEffects = new List<BaseEffect>();
sortedEffects.AddRange(animationEffects);
sortedEffects.AddRange(shakeEffects);
// 按 ListIndex 排序
sortedEffects = sortedEffects.OrderBy(effect => effect.ListIndex).ToList();
// 遍历排序后的效果列表,按顺序生成动画
foreach (var effect in sortedEffects)
{
Tweener tweener = effect.ApplyAnimation(transform);
if (tweener != null)
{
cachedAnimationSequence.Append(tweener);
}
}
// 如果需要让整个序列循环
if (loopEntireSequence)
{
cachedAnimationSequence.SetLoops(-1, sequenceLoopType);
}
// 标记动画序列已经更新
animationSequenceNeedsUpdate = false;
}
// 播放动画,如果动画序列需要更新则先更新
public void PlayAnimations()
{
if (animationSequenceNeedsUpdate)
{
UpdateAnimationSequence();
}
if (cachedAnimationSequence != null)
{
cachedAnimationSequence.Play();
}
}
// 停止动画
public void StopAnimations()
{
if (cachedAnimationSequence != null)
{
cachedAnimationSequence.Kill();
animationSequenceNeedsUpdate = true;
}
}
public void RestartAnimations()
{
if (cachedAnimationSequence != null)
{
Debug.Log("复位");
cachedAnimationSequence.Goto(0, true); // 跳到时间轴的起点并播放
//cachedAnimationSequence.Rewind();
//cachedAnimationSequence.Restart();
cachedAnimationSequence.Pause();
}
}
// 仅当 Inspector 中的值更改时才调用 OnValidate
private void OnValidate()
{
// 确保脚本初始化完成并且不在播放模式下运行
if (isInitialized && !Application.isPlaying)
{
Debug.Log("Inspector 中的值发生更改,动画更新");
animationSequenceNeedsUpdate = true;
}
}
}