在游戏中,我们可能需要这样的效果,将一个物体放大2倍,在2s之内完成;或者在点击UI时将UI逐渐消失。这样需要多作用效果进行逐步展示的效果被称之为补间。

为了引出我们今天的主角DOTween,我们先来看看用unity的animation系统制作一个帧动画序列。

普通的动画

我们需要以下几个步骤:
1. 创建并录制动画
2. 在Animator中设置
3. 绑定按钮事件

代码部分:

private static readonly int Play = Animator.StringToHash("Play");
public void StartAni()
{
    ui.GetComponent<Animator>().SetTrigger(Play);
    print("播放动画");
}

我们需要既需要创建资源,有需要绑定设置,操作过程略微麻烦。

DoTween动画

在DoTween中我们仅仅需要绑定好按钮事件即可,不要创建动画资源,设置动画播发器等麻烦事。
这在轻度使用补间动画里是非常不错的。

 public void StartAni()
{
    var rec = GetComponent<RectTransform>();
    rec.DOLocalMoveX(0, 2);
}

RectTransform组件,这是ui所特有的描述transform的组件,第二行代码我们使用扩展方法
让我们来分析一下这2行代码,第一行 我们找到UI的RectTransform组件,这是ui所特有的描述transform的组件,第二行代码我们使用扩展方法DOLocalMoveX对组件位置进行补间,目的地位置为0(此时也就是锚点的位置,我这里以中心作为锚点),第二个参数是完成动画的时间我选择2。也就是说在2s内让这个UI从飞到他x轴的锚点位置。

通用方法

上面的扩展方法我们也可以使用如下的通用方法来替代。

From动画


不论是我们使用扩展方法创建的动画还是通用方法创建的动画,我们都可以添加.Form()来设定为逆动画。

var rec = GetComponent<RectTransform>();
rec.DOLocalMoveX(0, 2).From();

知识速记(扩展方法)

扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型

如果之前的代码较多,在考虑重构时,扩展方法可比接口好用哦

小案例-打字机效果

public Text info;
[ResizableTextArea]public string infoData;
info.DOText(infoData, 3);

DoTween的约定

在详细讲解DoTween之前,我们先来了解一下dotween的设计原理和约定。
0. dotween使用tween(补间)来描述一段动画或缓动:
rec.DOLocalMoveX(0, 2).From()就是一个tween。
使用Sequence(序列)来表述一组tween,在下面介绍Sequence。

  1. 和我们平时使用unity一样,动态变化的部分防止在update或fiexedUpdate中,dotween也是这样的,在游戏启动时他会将所有的tween的放置在一个容器中(使用了对象池)。
  2. 不论是tween或者是Sequence默认都将在执行完成后自动杀死。
  3. tween默认使用timescale(也就是说我们常用的timescale=0暂停游戏也将暂停tween)

On事件监听

我们可以对一个序列或者一个补间注册事件监听状态。
以下是一些事件:

名称 描述
onComplete 注册完成委托
onKill 注册杀死委托
onPlaye 注册开始委托
onPause 注册暂停委托
onUpdate 注册更新委托
onRewind 注册倒带委托
OnStepComplete 每次循环完成时

每个委托都有对应的方法类型可使用。

transform.DOLocalMoveX(0, 2).onKill += () => { print("hi"); };
transform.DOLocalMoveX(0, 2).OnStart(() => print("开始了"));

Set设定

我们可以对一个序列或者一个补间设定细节。

setLoop设定循环

  • 参数一: 循环次数(设定为-1为无限循环)
  • 参数二: 循环类型
transform.DOLocalMoveX(0, 2).SetLoops(-1, LoopType.Incremental);
循环类型 说明
Incremental 递增,每次播放结束star和end都会加入到差异值中
Restart 重来,播放结束时从起点重新播放
Yoyo 摇摆播放

SetEase设定曲线

其他常用方法

  1. setLink(Gameobject) :
    将tween链接到游戏物体,在物体被销毁时自动销毁对象(在序列中无效)
  2. setId(object):
    设定tween的id,用于找到tween,使用数字时效率最高,字符串次之
  3. SetAutoKill(bool):
    设定tween执行完是否自动杀死,复用twenn设为false
  4. SetDelay(float):
    设定开始播放前的延迟
  5. SetUpdate(UpdateType):
    设定更新模式
  6. SetAs(tween):
    使用其他tween的设定模板

Sequence序列

将很多tween放在一起称为一个序列Sequence。

 var mySeq = DOTween.Sequence();
            mySeq.Append(rec.DOLocalMoveX(0, 2));
            mySeq.Append(info.DOText(infoData, 3));
            //在所有补间执行完时回调
            mySeq.AppendCallback(() => { print("动画播放完成!"); });
            //插入
            /*在给定的时间位置插入给定的补间,从而使您可以重叠补间,而不仅仅是将它们一个接一个地放置。*/
            mySeq.Insert(0.5f, rec.DOScaleX(2f, 2f));
            //给定时间插入回调
            mySeq.InsertCallback(2f, () => print("移动动画结束了"));
            //在序列开头插入补间
            mySeq.Prepend(info.DOText("在开头插入的补间。。。", 3));
            mySeq.PrependCallback((() => print("开头插入开始/动画开始播放")));
            //序列开始延迟
            mySeq.PrependInterval(2);
            //暂停序列
            // mySeq.Pause();

            //可以写在一起
             mySeq.Append(rec.DOLocalMoveX(0, 2))
                 .Append(info.DOText(infoData, 3))
                 .AppendCallback(() => { print("动画播放完成!"); });

DoTween和协程

看个例子:协程在完成动画之后执行

IEnumerator Wait()
{
    var tt = transform.DOMoveX(2, 2f);
    yield return tt.WaitForCompletion();

    print("动画完成");
}
方法 说明
WaitForElapsedLoops(int) 在循环指定次数或tween被杀死后
WaitForKill 在tween被杀死后
WaitForPosition 到达给定位置或被杀死
WaitForRewind 被杀死或重新播放
WaitForStart 开始播放

全局设定

我们可以使用DoTween类的静态字段来设置对应的默认行为。
如设定是否自动播放,是否自动销毁,对象池大小,默认曲线方式,所有的tween和Sequence序列在没有设定参数时默认取全局设定的值。
在Pro版本我们也可以在可视化面板中设置这些参数。

在运行游戏后我们可以发现场景中多了一个twenn的对象,上面可以在游戏中实时查看tween的信息。