一, 情景
虽然Unity提供了插值的算法,但是想来确实没有Falsh, Egret, Laya, Cocos Creator等给出的Tween方案来的爽,主要是不够方便.所以本人还是强烈建议使用Tween插件, 如DOTween.
二, 先举一个小栗子
1, scene布置如下:
2, 需求如下:
使Sphere(圆球) , 在2S的时间内匀速移动到(2,1,0)的位置
实现方案:
Ⅰ, DOTween的方案
代码挂载到Scripts空物体上,如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class DoTween3D : MonoBehaviour
{
[SerializeField]
private GameObject go;//我的小圆球啊
private Tweener tweener;
void Start()
{
this.tweener = this.go.transform.DOMove(new Vector3(2, 1, 0), 2.0f);//以秒为单位
tweener.SetAutoKill(false);
}
void Update()
{
}
}
并且, 圆球是可以到(2,1,0)的位置的,如下图
Ⅱ, Unity的插值方案
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lerp3D : MonoBehaviour
{
[SerializeField]
private GameObject go;//圆球
[SerializeField]
private AnimationCurve curve;
[SerializeField]
private float duration = 2.0f;
[SerializeField]
private Vector3 targetV3 = new Vector3(2, 1, 0);
private Vector3 initVe3;
private float curveX;
void Awake()
{
this.curveX = 0;
}
void Start()
{
this.initVe3 = this.go.transform.position;
}
// 可以达到目标
void Update()
{
this.curveX += Time.deltaTime / this.duration;
this.go.transform.position = Vector3.Lerp(this.initVe3, this.targetV3, this.curve.Evaluate(this.curveX));
}
}
感觉Tween的想法简单许多了. 这只是其中一部分
三, DoTween 常用API介绍
Ⅰ , 注意
1, 需要引用 using DG.Tweening;
2, DoMove() 方法修改的是世界坐标,要修改局部坐标请使用DoLocalMove()方法
3, DoMoveX()只是修改X轴方向上的移动,其他的轴上的移动有DoMoveY(),DoMoveZ()
4, DoPlayForward()正序播放 , DoPlayBackwards()倒序播放
好, 改一下我的scene, 做一个测试,如下
4-①, scene布置
4-②, 脚本代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
public class DoTween3D : MonoBehaviour
{
[SerializeField]
private GameObject go;//我的小圆球啊
[SerializeField]
private Button button;
[SerializeField]
private bool isZhengXu = true;
private Text buttonTxt;
private Tweener tweener;
void Start()
{
this.tweener = this.go.transform.DOMove(new Vector3(2, 1, 0), 2.0f);//以秒为单位
tweener.SetAutoKill(false);//禁止自动销毁动画
tweener.Pause();//暂停
this.buttonTxt = this.button.GetComponentInChildren<Text>();
this.ResetBtnTxt();
this.AddEvent();
}
private void AddEvent()
{
this.button.onClick.AddListener(this.OnClickHandler);
}
private void RemoveEvent()
{
this.button.onClick.RemoveListener(this.OnClickHandler);
}
private void OnClickHandler()
{
if (this.isZhengXu)
{
this.tweener.PlayForward();
}
else
{
this.tweener.PlayBackwards();
}
this.isZhengXu = !this.isZhengXu;
this.ResetBtnTxt();
}
private void ResetBtnTxt()
{
if (this.isZhengXu)
{
this.buttonTxt.text = "正播";
}
else
{
this.buttonTxt.text = "倒播";
}
}
void Update()
{
}
void OnDestroy()
{
//销毁缓动
if (this.tweener != null)
{
this.tweener.Kill();
this.tweener = null;
}
}
}
5,Sequence
5-①,相当于一个Tweener的链表,可以通过执行一个Sequence来执行一串Tweener,使用Sequence类可以方便的组织Tweens来制作复杂的过渡动画
5-②,提供的方法:
5-2-①,Append(Tweener tween),加添一个tween
5-2-②,AppendCallback(TweenCallback callback),添加一个回调
5-2-③,AppendInterval(float interval),添加一段时间间隔
5-2-④, Insert(float atPosition, Tweener tween),插入一段缓动(在给定的时间位置上)
5-2-⑤,InsertCallback(float atPosition, TweenCallback callback),插入一段回调(在给定的时间位置上)
5-2-⑥, Join(Tween tween), 在Sequence的最后一个tween的开始处放置一个tween
5-2-⑦,Prepend(Tween tween),在Sequence开始处插入一个tween
5-2-⑧,PrependCallback(TweenCallback callback),在Sequence开始处插入一个回调函数
5-2-⑨,PrependInterval(float interval),在Sequence开始处插入一段时间间隔
5-③,Demo如下
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
public class Sequence3D : MonoBehaviour
{
[SerializeField]
private GameObject go;
private Sequence sequence;
void Start()
{
this.sequence = DOTween.Sequence();
this.sequence.Append(this.go.transform.DOMove(new Vector3(2, 1, 0), 2f));//添加一个补间动画
this.sequence.Append(this.go.transform.DORotate(new Vector3(90, 90, 0), 2f));//添加一个旋转动画(DOMove执行后之执行)
this.sequence.Insert(0, this.go.transform.DOScale(new Vector3(1.5f, 2, 1), 2));//在0s吃添加一个缩放动画(并行执行和DOMove,因为DOMove在0s执行)
this.sequence.PrependInterval(5);//在开始处添加5秒等待,5S后还是执行DOMove和DOScale
}
void Update()
{
}
void OnDestroy()
{
if (this.sequence != null)
{
this.sequence.Kill();
this.sequence = null;
}
}
}
效果如下:
Ⅱ, 常用的方法总结:
1.以DO开头的方法:补间动画的方法。例如:Transform.DOMoveX(10,1)
2.以Set开头的方法:设置补间动画的属性。例如:Tweener.SetLoops(4, LoopType.Yoyo)
3.以On开头的方法:补间动画的回调函数。例如:Tweener.OnStart(callBackFunction)