在游戏中,我们可能需要这样的效果,将一个物体放大 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 动画

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 的信息。

# 复用动画

2021 年 12 月 9 日 18:37:03 更新

// 创建一个序列
private Sequence seq;
// 设置序列
private void Awake()
{
	seq = DOTween.Sequence();
	seq.Append(titleTxt.rectTransform.DOLocalMoveX(-1500, 1f).From());
	seq.Append(titleTxt.DOFade(0, 0.5f).SetDelay(0.5f));
	seq.SetLink(titleTxt.gameObject).AppendCallback(() => { endBtn.gameObject.SetActive(true); })
                .PrependCallback(
                    () => { endBtn.gameObject.SetActive(false); 				}).SetAutoKill(false);
}
// 第二次启用时需要这个
seq.Restart();
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Fasty 微信支付

微信支付

Fasty 支付宝

支付宝

Fasty 贝宝

贝宝