遇到问题
由于项目存在大量模型动画,如果一个个去写动画,会耗费大量时间。。。不如自己写一个全部通用的动画工具脚本
实现功能需求
- 可用于步骤拆解动画、流程动画、复杂的动画等都可以实现
- 可进行原位置动画还原
- 可进行动画功能扩展
- 只需要调用已经写好的接口就可以
使用步骤(最下面放脚本内容)
1.导入Dotween插件,Dotween插件官网: http://dotween.demigiant.com
(这个我就不教了,大家肯定都会)
2.新建一个空物体作为动画管理物体,脚本挂载上(注意:图上脚本,在文章最下边获取!)
3.下面可以自由组合动画
每一个建立的空物体都有挂载GenericDeviceDisassembly脚本,到时候用到哪一组动画就调用这一个动画的物体获取到GenericDeviceDisassembly脚本,调已经写好的播放方法即可
使用脚本如下:
Unity管理组合如下(根据情况随意搭建父子级):
4.GenericDeviceDisassembly脚本内容如下:
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GenericDeviceDisassembly : MonoBehaviour
{
private void Awake()
{
// 初始化每个拆解步骤的原始状态
foreach (var step in steps)
{
step.SaveOriginalState();
}
}
private void Start()
{
StartDisassembly();
}
private bool isTrue = true;
private void Update()
{
if (Input.GetKeyDown(KeyCode.T) && isTrue) //还原动画测试 ,后续可删除
{
isTrue = false;
InitializeAnimation();
}
}
// 定义拆解步骤的类
[System.Serializable]
public class DisassemblyStep
{
public Transform target; // 要拆解的部件
public Vector3 moveTo = Vector3.zero; // 拆解时的目标位置(可选)
public Vector3 rotateTo = Vector3.zero; // 拆解时的目标旋转(可选)
public float duration = 1f; // 动画持续时间 如果 0 动画会动不了
public Ease ease = Ease.Linear; // 缓动函数
public float delay = 0f; // 动画延迟
//保存原始的位置
public Vector3 originalPosition;
public Quaternion originalRotation; // 使用Quaternion来保存旋转
// 初始化时保存原始状态
public void SaveOriginalState()
{
if (target != null)
{
originalPosition = target.position;
originalRotation = target.rotation; // 保存完整的旋转Quaternion
}
}
// 如果需要更复杂的动作,在这里添加字段
}
public List<DisassemblyStep> steps = new List<DisassemblyStep>(); // 拆解步骤列表
// 拆解动画的触发方法
public void StartDisassembly()
{
Sequence sequence = DOTween.Sequence(); // 创建一个Sequence以控制动画的顺序
foreach (var step in steps)
{
if (step.target != null) // 确保目标Transform不为空
{
if (step.moveTo != Vector3.zero)
{
sequence.Append(step.target.DOMove(step.moveTo, step.duration).SetEase(step.ease).SetDelay(step.delay));
}
if (step.rotateTo != Vector3.zero)
{
// 如果需要精确的Quaternion旋转,请确保rotateTo是有效的欧拉角,并转换为Quaternion
sequence.Append(step.target.DORotate(step.rotateTo, step.duration, RotateMode.LocalAxisAdd).SetEase(step.ease).SetDelay(step.delay));
}
// 如果只想在第一个非零延迟处开始计时,可以调整这里的延迟逻辑
// 例如,可以设置一个标志来检查是否已经添加了第一个带延迟的步骤
}
else
{
Debug.LogError("DisassemblyStep target 不存在!", this);
}
}
}
// 停止拆解动画(如果需要的话)
public void StopDisassembly()
{
// 停止当前GameObject及其所有子对象上的所有DoTween动画
DOTween.KillAll(true, this.gameObject);
}
// 初始化动画方法,将部件移回原始位置和旋转
public void InitializeAnimation(float duration = 0.5f, float delayBetweenSteps = 0f)
{
Sequence sequence = DOTween.Sequence();
for (int i = 0; i < steps.Count; i++)
{
var step = steps[i];
if (step.target != null)
{
sequence.Append(step.target.DOMove(step.originalPosition, duration).SetEase(Ease.Linear));
sequence.Append(step.target.DORotateQuaternion(step.originalRotation, duration).SetEase(Ease.Linear));
// 如果需要步骤之间有延迟
if (i < steps.Count - 1 && delayBetweenSteps > 0)
{
sequence.AppendInterval(delayBetweenSteps);
}
}
}
}
private void OnDestroy()
{
StopDisassembly();
}
}
5.如果使用中有什么问题,可在我文章下面留言哦!