Unity DoTween 详解
一、概述
DoTween(现称为 DG.Tweening)是一个功能强大、性能优异的Unity动画插件,它提供了比Unity原生动画系统更简洁、更灵活的API来创建各种补间动画。
二、安装方法
1. 从Asset Store安装(推荐新手)
-
在Unity Asset Store中搜索”DOTween (HOTween v2)”
-
免费版功能完整,专业版(收费)提供额外功能
2. 通过Git URL安装(Package Manager)
-
打开Package Manager → Add package from git URL
-
输入:https://github.com/Demigiant/dotween.git?path=Demigiant/DOTween/Assets/DOTween
3. 安装后设置
1 2 3 4 5
| // 第一次使用前需初始化 using DG.Tweening; void Start() { DOTween.Init(); }
|
三、核心功能与语法
1. 基本动画方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| // 移动 transform.DOMove(new Vector3(10, 0, 0), 1f); // 1秒移动到(10,0,0) transform.DOLocalMoveX(5, 2f); // 沿本地X轴移动
// 旋转 transform.DORotate(new Vector3(0, 360, 0), 2f, RotateMode.FastBeyond360); transform.DOLocalRotate(new Vector3(0, 180, 0), 1f);
// 缩放 transform.DOScale(2f, 1f); // 缩放到2倍 transform.DOScale(new Vector3(1, 2, 1), 1f); // 非均匀缩放
// 颜色(UI/材质) Image img = GetComponent<Image>(); img.DOColor(Color.red, 0.5f); img.DOFade(0, 1f); // 淡出
// 数值变化 int score = 0; DOTween.To(() => score, x => score = x, 100, 2f);
|
2. 链式调用(Fluent API)
1 2 3 4 5 6 7
| transform.DOMoveX(5, 1f) .SetEase(Ease.OutBounce) .SetDelay(0.5f) .OnComplete(() => { Debug.Log("移动完成!"); }) .SetLoops(2, LoopType.Yoyo); // 来回运动2次
|
四、核心设置与配置
1. 缓动函数(Easing)
1 2 3 4 5 6 7 8 9 10 11
| // 常用缓动类型 .SetEase(Ease.Linear) // 线性 .SetEase(Ease.InOutQuad) // 平滑进出 .SetEase(Ease.OutBack) // 回弹效果 .SetEase(Ease.InElastic) // 弹性效果 .SetEase(Ease.InBounce) // 弹跳效果 .SetEase(Ease.InSine) // 正弦曲线
// 自定义曲线 [SerializeField] AnimationCurve customCurve; .SetEase(customCurve)
|
2. 循环与重复
1 2 3
| .SetLoops(3, LoopType.Restart) // 重复3次 .SetLoops(-1, LoopType.Yoyo) // 无限来回运动 .SetLoops(2, LoopType.Incremental) // 增量式循环
|
3. 回调函数
1 2 3 4 5
| .OnStart(() => Debug.Log("动画开始")) .OnPlay(() => Debug.Log("动画播放")) .OnUpdate(() => Debug.Log("每帧调用")) .OnComplete(() => Debug.Log("动画完成")) .OnKill(() => Debug.Log("动画被杀死"))
|
五、序列动画(Sequence)
1. 基本序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Sequence mySequence = DOTween.Sequence();
// 按顺序执行 mySequence.Append(transform.DOMoveX(5, 1f)); mySequence.Append(transform.DORotate(new Vector3(0, 180, 0), 1f)); mySequence.Append(transform.DOScale(2, 1f));
// 同时执行 mySequence.Join(transform.DOShakeScale(1f));
// 插入动画 mySequence.Insert(0.5f, transform.DOMoveY(2, 1f)); // 在0.5秒时插入
// 预置间隔 mySequence.AppendInterval(1f); // 等待1秒
// 链式设置 mySequence.SetLoops(-1).SetEase(Ease.Linear);
|
2. 高级序列控制
1 2 3 4 5 6 7 8 9
| Sequence seq = DOTween.Sequence() .Append(transform.DOMoveX(5, 1)) .AppendCallback(() => Debug.Log("第一步完成")) .Append(transform.DOMoveY(3, 1)) .SetAutoKill(false) // 不自动销毁 .Pause(); // 创建后暂停
// 稍后播放 seq.Play();
|
六、特殊效果
1. 相机震动
1 2 3 4 5 6 7 8 9 10 11
| // 位置震动 transform.DOShakePosition(1f, strength: 0.3f, vibrato: 10, randomness: 90);
// 旋转震动 transform.DOShakeRotation(1f, strength: 10f);
// 缩放震动 transform.DOShakeScale(1f, strength: 0.5f);
// 相机专用震动(屏幕震动) Camera.main.DOShakePosition(0.5f, strength: 0.1f);
|
2. 路径动画
1 2 3 4 5 6 7 8 9
| Vector3[] path = new Vector3[] { new Vector3(0, 0, 0), new Vector3(5, 2, 0), new Vector3(10, 0, 0) };
transform.DOPath(path, 3f, PathType.CatmullRom) .SetOptions(true) // 闭合路径 .SetLookAt(0.01f); // 朝向移动方向
|
3. UI动画
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 文本动画 Text textComponent = GetComponent<Text>(); textComponent.DOText("Hello World!", 2f); // 打字机效果 textComponent.DOColor(Color.red, 1f); textComponent.DOFade(0, 1f);
// 填充动画 Image image = GetComponent<Image>(); image.DOFillAmount(1, 2f); // 2秒内填满
// 布局动画 LayoutElement layout = GetComponent<LayoutElement>(); layout.DOPreferredSize(new Vector2(200, 100), 1f);
|
七、性能优化与内存管理
1. 对象池与重用
1 2 3 4 5 6 7 8 9 10 11 12
| // 创建可重用的Tween Tween myTween = transform.DOMoveX(10, 1f) .SetAutoKill(false) // 不自动回收 .SetRecyclable(true) // 可回收重用 .Pause();
// 重用 myTween.Restart();
// 手动管理 DOTween.Clear(); // 清除所有Tween DOTween.ClearCachedTweens(); // 清除缓存的Tween
|
2. 性能设置
1 2 3 4 5 6 7 8 9
| // 全局设置 DOTween.SetTweensCapacity(200, 50); // 设置Tween和序列的容量
// 时间缩放独立 transform.DOMoveX(5, 1f).SetUpdate(true); // 使用非缩放时间
// 性能模式 DOTween.defaultEaseType = Ease.Linear; DOTween.useSafeMode = true; // 安全模式(推荐开发时使用)
|
八、高级特性
1. From 动画
1 2 3
| // 从指定值开始动画 transform.DOMoveX(5, 1f).From(); // 从当前位置移动到5 transform.DOMoveX(5, 1f).From(true); // 从5移动到当前位置
|
2. 相对动画
1
| transform.DOMoveX(5, 1f).SetRelative(); // 相对当前位置移动5个单位
|
3. 控制与状态查询
1 2 3 4 5 6 7 8 9 10 11 12 13
| Tween tween = transform.DOMoveX(10, 2f);
// 控制 tween.Pause(); tween.Play(); tween.TogglePause(); tween.Rewind(); // 重播 tween.Complete(); // 立即完成
// 状态查询 bool isPlaying = tween.IsPlaying(); bool isComplete = tween.IsComplete(); float elapsed = tween.Elapsed(); // 已过去的时间
|
九、实用示例
1. 按钮点击动画
1 2 3 4
| public void OnButtonClick() { transform.DOScale(0.9f, 0.1f) .OnComplete(() => transform.DOScale(1f, 0.1f)); }
|
2. 对象淡入淡出
1 2 3 4 5 6 7 8
| public IEnumerator FadeInOut(GameObject obj) { CanvasGroup cg = obj.GetComponent<CanvasGroup>(); if (cg == null) cg = obj.AddComponent<CanvasGroup>(); yield return cg.DOFade(1, 0.5f).WaitForCompletion(); yield return new WaitForSeconds(2f); yield return cg.DOFade(0, 0.5f).WaitForCompletion(); }
|
3. 分数计数动画
1 2 3 4 5 6 7 8 9 10 11 12
| public Text scoreText; private int _score = 0;
public void AddScore(int points) { int oldScore = _score; _score += points; DOTween.To(() => oldScore, x => scoreText.text = $"Score: {x}", _score, 0.5f) .SetEase(Ease.OutQuad); }
|
十、最佳实践与常见问题
1. 最佳实践
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 1. 初始化一次 void Start() { DOTween.Init(autoKillMode: false, useSafeMode: true, logBehaviour: LogBehaviour.ErrorsOnly); }
// 2. 对象销毁时清理 void OnDestroy() { transform.DOKill(); // 杀死此Transform的所有Tween }
// 3. 使用WaitForCompletion等待 yield return transform.DOMoveX(10, 2f).WaitForCompletion();
// 4. 避免内存泄漏 DOTween.KillAll(); // 场景切换时清理
|
2. 常见问题解决
-
问题:动画结束后对象不恢复
1 2
| // 使用From()时注意方向 transform.DOScale(0, 1f).From(); // 从0缩放到当前尺寸
|
-
问题:动画卡顿
1 2
| // 减少同时运行的Tween数量 // 使用SetUpdate(UpdateType.Fixed)用于物理相关
|
-
问题:编辑器模式不工作
1 2 3 4
| // 确保在编辑器运行模式下测试 #if UNITY_EDITOR DOTween.Init(true, true, LogBehaviour.Verbose); #endif
|
十一、与Unity协程配合
1 2 3 4 5
| IEnumerator AnimationSequence() { yield return transform.DOMoveX(5, 1f).WaitForCompletion(); yield return new WaitForSeconds(0.5f); yield return transform.DORotate(new Vector3(0, 180, 0), 1f).WaitForCompletion(); }
|
总结
DoTween是Unity中最流行的动画插件之一,其特点包括:
-
✅ API简洁直观,链式调用流畅
-
✅ 性能优异,对象池管理内存
-
✅ 功能全面,支持各种动画类型
-
✅ 与Unity深度集成,支持UI、2D、3D
-
✅ 社区活跃,文档完善
学习建议:从简单的DOMove/DOScale开始,逐步掌握Sequence和高级特性,注意内存管理和性能优化。