前言

在边做比赛项目边学习的过程中,我不仅了解到设计模式那般优雅的解决方案,还了解了另一种精致的工具——Unity的插件。像我们最常用的 TMPro 就是Unity插件的一种。Unity众多的插件不光可以节省我们的开发时间,还可以为我们提供出乎意料的神秘技能,本文将推荐一款好用的动画插件——DOTween


插件介绍

DOTween 概述

DOTween 是 Unity 中最受欢迎的补间动画(Tweening)插件之一,它提供了一个高效、灵活且易于使用的动画系统。作为 HOTween 的继承者,DOTween 在性能、功能和易用性方面都有显著提升。

核心特性

高性能

  • 零分配内存操作(Zero-allocation)
  • 高度优化的代码结构
  • 比 Unity 原生动画系统更高效

丰富的功能集

  • 支持 TransformMaterialCameraUI 等多种对象动画
  • 路径动画功能
  • 序列动画系统
  • 回调函数支持
  • 物理模拟动画

3. 简洁的 API 设计

  • 链式调用语法
  • 直观的命名规则
  • 丰富的扩展方法

基本使用

安装与设置

通过 Unity Asset StoreGitHub 获取 DOTween,导入后需初始化:

1
2
3
4
5
6
using DG.Tweening;

void Start() {
// 初始化DOTween(自动完成)
DOTween.Init(autoKillMode, useSafeMode, logBehaviour);
}

基本补间动画

1
2
3
4
5
6
7
8
9
10
11
// 移动物体
transform.DOMove(new Vector3(2, 2, 2), 1f);

// 缩放物体
transform.DOScale(new Vector3(1.5f, 1.5f, 1.5f), 0.5f);

// 旋转物体
transform.DORotate(new Vector3(0, 90, 0), 1f);

// 颜色渐变
material.DOColor(Color.red, 1f);

链式调用

1
2
3
transform.DOMoveX(5, 1f)
.SetEase(Ease.OutBounce)
.OnComplete(() => Debug.Log("移动完成!"));

高级功能

动画序列(Sequences)

1
2
3
4
5
Sequence mySequence = DOTween.Sequence();
mySequence.Append(transform.DOMoveX(5, 1f));
mySequence.AppendInterval(0.5f);
mySequence.Append(transform.DOScale(2, 0.5f));
mySequence.Play();

路径动画

1
2
3
Vector3[] path = new Vector3[] { /* 路径点 */ };
transform.DOPath(path, 5f, PathType.CatmullRom)
.SetLookAt(0.01f);

回调系统

1
2
3
4
transform.DOMoveX(5, 1f)
.OnStart(() => Debug.Log("动画开始"))
.OnUpdate(() => Debug.Log("动画进行中"))
.OnComplete(() => Debug.Log("动画完成"));

动画控制

1
2
3
4
5
6
7
8
9
10
11
Tween myTween = transform.DOMoveX(5, 1f);

// 暂停/继续
myTween.Pause();
myTween.Play();

// 重设动画
myTween.Rewind();

// 完成动画
myTween.Complete();

UI 动画支持

DOTween 对 Unity UI 有特别优化:

1
2
3
4
5
6
7
8
9
10
11
// 文本动画
text.DOText("新文本", 1f);

// 颜色渐变
image.DOColor(Color.blue, 0.5f);

// 淡入淡出
canvasGroup.DOFade(0, 1f);

// UI 元素移动
rectTransform.DOAnchorPos(new Vector2(100, 100), 1f);

性能优化技巧

  1. 对象池DOTween 自动管理补间对象池
  2. 重用补间:避免频繁创建新补间
  3. 批量控制:使用 DOTween.To() 批量处理
  4. 合理设置 Update 类型
    1
    2
    3
    4
    myTween.SetUpdate(UpdateType.Normal); // 默认
    myTween.SetUpdate(UpdateType.Late); // LateUpdate
    myTween.SetUpdate(UpdateType.Fixed); // FixedUpdate
    myTween.SetUpdate(true); // 使用独立时间不受Time.timeScale影响

最佳实践

  1. 使用静态扩展方法

    1
    DOTween.To(() => myValue, x => myValue = x, 10, 1f);
  2. 组合动画

    1
    transform.DOMoveX(5, 1f).Join(transform.DORotate(new Vector3(0,180,0), 1f));
  3. 自定义缓动函数

    1
    2
    3
    myTween.SetEase(Ease.InOutQuad);
    // 或使用动画曲线
    myTween.SetEase(myAnimationCurve);
  4. 性能监控

    1
    2
    DOTween.SetTweensCapacity(200, 50); // 设置最大补间数
    Debug.Log(DOTween.TotalPlayingTweens); // 监控当前补间数

DOTween 的强大之处在于它的灵活性和高性能,掌握这些功能可以显著提升 Unity 项目的动画效果和开发效率。

文章只列出了 DOTWeen 大致的函数调用,想了解具体函数的调用规则与细节,或者对插件感兴趣可以访问 DOTween官网


使用心得

因为这段时间一直在写2D游戏,所以用在UI上比较多,下面分享一些我的用法:

卡牌动画

在TapTap的GameJam上做的卡牌之光游戏的卡牌效果就用到了DOTween,包括鼠标进入与离开的反馈、抽牌和使用的动画等。因为动画逻辑写的比较杂,就不放代码了。

按钮效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void OnPointerClick(PointerEventData eventData)
{
    // 缩小按钮
    transform.DOScale(new Vector3(1, 1, 1) * 0.9f, 0.1f)
        .OnComplete(() =>
        {
            // 播放音效
            AudioManager.Instance.PlayEffect();
            // 恢复按钮大小
            transform.DOScale(new Vector3(1, 1, 1), 0.1f)
            .OnComplete(() =>
            {
                onClick?.Invoke(gameObject, eventData);
            });
        });
}

还记得UI的EventTrigger吗? UI的构建
在鼠标点击方法中,我在执行事件函数之前添加了缩小和恢复两段动画,就实现了弹性的按钮啦。

按钮效果

Tips提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void ShowTip(string msg, Color color, System.Action callback = null)
{
    GameObject obj = Instantiate(Resources.Load("UI/Tips"), canvasTf) as GameObject;
    Text text = obj.transform.Find("bg/Text").GetComponent<Text>();
    text.color = color;
    text.text = msg;
    Tween scale1 = obj.transform.Find("bg").DOScaleY(1, 0.4f);
    Tween scale2 = obj.transform.Find("bg").DOScaleY(0, 0.4f);

    Sequence seq = DOTween.Sequence();
    seq.Append(scale1);
    seq.AppendInterval(0.5f);
    seq.Append(scale2);
    seq.AppendCallback(delegate()
    {
        if (callback != null)
        {
            callback();
        }
    });

    MonoBehaviour.Destroy(obj, 2);
}

我让一张图片生成时渐渐变宽,就形成了Tips效果。

Tips

翻页效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 翻页动画(左)
public void FilpPageEffectLeft()
{
    transform.Find("bgmask").gameObject.SetActive(true);
    transform.SetAsLastSibling();

    // 向左位移
    ((RectTransform)transform).DOAnchorPosX(-Screen.width, 1f)
        .SetEase(Ease.InOutQuad)
        .OnComplete(() =>
        {
            Close();
        });
}

通过改变上一级UI的关闭动画实现了翻页效果。

翻页效果

我用了几天的时间闲的没事做了一个抽奖玩法的手机小游戏,将这一系列动画效果集成在了这个小游戏中,使UI”活蹦乱跳”,我将连接放在这里了啦:
GitHub仓库 -> 读博模拟器
感兴趣可以体验一下。


结语

在Unity开发中,强大的插件生态能极大提升开发效率与游戏表现。DOTween作为动画系统的标杆,以它简洁的API、卓越的性能和丰富的功能,让复杂的动画效果变得触手可及。无论是UI交互、角色动作还是场景过渡,DOTween都能轻松胜任,成为开发者工具箱中不可或缺的利器。

当然,Unity的插件宇宙远不止于此。Unity众多的插件如同游戏开发的”加速器”,帮助开发者将创意快速转化为现实。但切记:插件是工具而非依赖,合理选择、适度使用才是关键。理解底层原理,结合项目需求,才能让插件真正发挥价值。

希望本文的推荐能为你的Unity开发之旅提供灵感。如果你有其他优秀的插件推荐,或对DOTween的使用有独到见解,欢迎在评论区分享交流!

—end—