| name | doTween-unity |
| description | DOTween Unity 动画插件。用于补间动画、UI 过渡、相机震动、序列、TextMeshPro 动画以及 Unity 中任何动画需求。此 Skill 应用于 Unity 项目中与 DOTween 动画系统相关的所有任务。 |
DOTween Unity Skill
DOTween (DG.Tweening) 是一个快速、高效、类型安全的 Unity 动画引擎,支持动画所有内容,包括 Transform、UI、Material、颜色、文本等。
何时使用此 Skill
在以下情况下触发此 Skill:
- DOTween 动画插件 (Demigiant/DOTween)
- UI 动画和过渡效果 (UI animations and transitions)
- Transform 动画 (位置、旋转、缩放)
- Material 和 Color 动画
- 相机震动和屏幕特效 (Camera shake and screen effects)
- 动画序列和时序控制 (Animation sequences)
- 延迟执行和回调 (Delays and callbacks)
- TextMeshPro 文字打字机效果
- 自定义扩展方法 (OHExtend.cs 中的扩展)
- OH 框架特定的 UI 动画效果
快速参考
Hello World - 基础动画
using DG.Tweening;
transform.DOMove(new Vector3(10, 0, 5), 1f);
transform.DOLocalMoveX(10f, 1f);
transform.DORotateQuaternion(Quaternion.Euler(0, 90, 0), 1f);
transform.DORotate(new Vector3(0, 360, 0), 1f, RotateMode.WorldAxisAdd);
transform.DOScale(2f, 0.5f);
image.DOFade(0f, 1f);
transform.DOMoveX(10, 1f).SetEase(Ease.OutBounce).SetLoops(-1, LoopType.Yoyo);
1. Transform 动画
位置动画
using DG.Tweening;
transform.DOMove(new Vector3(10, 0, 5), 1f);
transform.DOMoveX(10f, 1f);
transform.DOMoveY(5f, 1f);
transform.DOMoveZ(0f, 1f);
transform.DOLocalMove(new Vector3(10, 0, 5), 1f);
transform.DOLocalMoveX(10f, 1f);
transform.DOLocalMoveY(5f, 1f);
transform.DOLocalMoveZ(0f, 1f);
transform.DOJump(targetPosition, jumpPower: 2f, numJumps: 2, duration: 1f);
旋转动画
transform.DORotate(new Vector3(0, 90, 0), 1f);
transform.DORotateQuaternion(Quaternion.Euler(0, 90, 0), 1f);
transform.DOLocalRotate(new Vector3(0, 360, 0), 1f, RotateMode.WorldAxisAdd);
缩放动画
transform.DOScale(2f, 0.5f);
transform.DOScale(new Vector3(2, 1, 0.5f), 0.5f);
transform.DOScaleX(2f, 0.5f);
transform.DOScaleY(0.5f, 0.5f);
transform.DOScaleZ(1.5f, 0.5f);
transform.DOPunchScale(new Vector3(0.2f, 0.2f, 0.2f), 0.5f, 2, 0.5f);
2. UI 动画
using DG.Tweening;
using UnityEngine.UI;
rectTransform.DOAnchorPos(new Vector2(100, 100), 0.5f);
rectTransform.DOAnchorPosX(100f, 0.5f);
rectTransform.DOAnchorPosY(100f, 0.5f);
rectTransform.DOAnchorPos3D(new Vector3(100, 100, 0), 0.5f);
rectTransform.DOSizeDelta(new Vector2(200, 100), 0.5f);
image.DOColor(Color.red, 1f);
image.DOFade(0f, 1f);
image.DOFade(1f, 1f);
canvasGroup.DOFade(1f, 0.3f);
text.DOColor(Color.yellow, 1f);
text.DOFade(0f, 1f);
text.DOText("Hello World!", 2f, richTextEnabled: true);
3. Material 动画
material.DOColor(Color.blue, 1f);
material.DOColor(Color.white, "_EmissionColor", 1f);
material.DOFade(0f, 1f);
material.DOColor(new Color(0, 0, 0, 0), 1f);
material.DOFloat(1f, "_Metallic", 1f);
material.DOVector(Vector4.one, "_Color", 1f);
4. 相机动画
using DG.Tweening;
camera.DOOrthoSize(5f, 1f);
camera.DOFieldOfView(60f, 1f);
camera.DOColor(Color.black, 2f);
camera.DOShakePosition(1f, strength: new Vector3(1, 1, 0), vibrato: 10, randomness: 90);
camera.DOShakeRotation(1f, strength: 10, vibrato: 10, randomness: 90);
5. TextMeshPro 动画
using DG.Tweening;
using TMPro;
textMeshPro.DOColor(Color.yellow, 1f);
textMeshPro.DOFade(0f, 1f);
textMeshPro.DOFontSize(48f, 0.5f);
textMeshPro.DOMaxVisibleCharacters(textMeshPro.textInfo.characterCount, 2f);
6. 震动和冲击效果
using DG.Tweening;
transform.DOShakePosition(duration: 1f, strength: 1f, vibrato: 10, randomness: 90);
transform.DOShakeRotation(duration: 1f, strength: 45f, vibrato: 10);
transform.DOShakeScale(duration: 0.5f, strength: 0.5f, vibrato: 10);
transform.DOPunchPosition(direction: transform.up * 2, duration: 0.5f, vibrato: 10, elasticity: 0.5f);
transform.DOPunchRotation(rotation: new Vector3(0, 0, 90), duration: 0.5f, vibrato: 10, elasticity: 0.5f);
transform.DOPunchScale(punch: Vector3.one * 0.5f, duration: 0.5f, vibrato: 10, elasticity: 0.5f);
7. 回调和延迟
using DG.Tweening;
transform.DOMoveX(10, 1f).OnComplete(() => Debug.Log("Animation completed!"));
transform.DOMoveX(10, 1f).OnUpdate(() => Debug.Log("Animating..."));
transform.DOMoveX(10, 1f).OnStart(() => Debug.Log("Animation started!"));
DOTween.DelayedCall(1f, () => Debug.Log("Executed after 1 second"));
transform.DOMoveX(10, 1f)
.OnStart(() => Debug.Log("Started"))
.OnUpdate(() => Debug.Log("Updating"))
.OnComplete(() => Debug.Log("Completed"));
8. 循环动画
using DG.Tweening;
transform.DOMoveY(10, 0.5f).SetLoops(-1, LoopType.Yoyo);
transform.DOScale(2f, 0.5f).SetLoops(3, LoopType.Yoyo);
transform.DOMoveX(10, 1f).SetLoops(3, LoopType.Restart).SetEase(Ease.InOutSine);
9. 序列动画
using DG.Tweening;
Sequence seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f));
seq.Append(transform.DOScale(2f, 0.5f));
seq.Append(transform.DORotate(new Vector3(0, 90, 0), 0.5f));
seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f));
seq.Join(transform.DOScale(2f, 1f));
seq.Append(transform.DORotate(new Vector3(0, 90, 0), 0.5f));
seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f))
.Join(transform.DOScale(2f, 1f))
.Append(transform.DORotate(new Vector3(0, 90, 0), 0.5f));
seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f));
seq.Insert(0.5f, transform.DOScale(2f, 1f));
seq.Append(transform.DORotate(new Vector3(0, 90, 0), 0.5f));
seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f))
.AppendCallback(() => Debug.Log("Move completed"))
.Append(transform.DOScale(2f, 0.5f))
.AppendCallback(() => Debug.Log("Scale completed"));
seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f));
seq.AppendInterval(1f);
seq.Append(transform.DOScale(2f, 0.5f));
10. 协程和异步
using DG.Tweening;
using System.Collections;
IEnumerator CoroutineExample() {
Tween tween = transform.DOMoveX(10f, 1.5f);
yield return tween.WaitForCompletion();
transform.DOScale(2f, 0.5f);
yield return new WaitForSeconds(1f);
transform.DORotate(new Vector3(0, 90, 0), 1f);
yield return new WaitForSeconds(1f);
Debug.Log("Sequence completed");
}
IEnumerator WaitForOtherWays() {
yield return transform.DOMoveX(10f, 1.5f).WaitForKill();
yield return transform.DOMoveX(10f, 1.5f).WaitForElapsedLoops(2);
yield return transform.DOMoveX(10f, 1.5f).WaitForPosition(0.5f);
}
async void AsyncExample() {
await transform.DOMoveX(10f, 1.5f).ToUniTask();
await transform.DOScale(2f, 0.5f).ToUniTask();
await transform.DORotate(new Vector3(0, 90, 0), 1f).ToUniTask();
Debug.Log("Sequence completed");
}
11. 控制动画
using DG.Tweening;
Tweener tween = transform.DOMoveX(10, 1f);
if (tween.active()) {
Debug.Log("Animation is active");
}
tween.Pause();
tween.Play();
tween.Flip();
tween.Restart();
tween.Rewind();
tween.Kill();
tween.Kill(complete: false);
tween.Kill(complete: true);
tween.Complete();
DOTween.KillAll();
DOTween.Kill(transform);
DOTween.PauseAll();
DOTween.Pause(transform);
DOTween.Clear();
DOTween.Clear(transform);
Debug.Log($"Elapsed time: {tween.Elapsed()}");
Debug.Log($"Position (percentage): {tween.Position()}");
Debug.Log($"Elapsed percentage: {tween.ElapsedPercentage()}");
12. 缓动函数
using DG.Tweening;
transform.DOMoveX(10, 1f).SetEase(Ease.InOutSine);
transform.DOScale(2f, 0.5f).SetEase(Ease.OutBounce);
image.DOFade(0f, 1f).SetEase(Ease.InQuad);
AnimationCurve customCurve = new AnimationCurve();
customCurve.AddKey(0, 0);
customCurve.AddKey(1, 1);
transform.DOMoveX(10, 1f).SetEase(customCurve);
transform.DOMoveX(10, 1f).SetEase((float time, float duration, float overshootOrAmplitude, float period) => {
return time;
});
13. 设置选项
using DG.Tweening;
transform.DOMoveX(10, 1f)
.SetEase(Ease.OutBounce)
.SetLoops(3, LoopType.Yoyo)
.SetDelay(0.5f)
.SetRelative(true)
.SetAutoKill(true)
.SetRecyclable(true)
.SetUpdate(true);
transform.DOLocalMoveX(5, 1f).SetRelative(true);
transform.DOMoveX(10, 1f).SetDelay(0.5f);
transform.DOMove(targetPosition, 1f).SetSpeedBased();
text.DOText("Hello World", 2f).SetOptions(scrambleMode: ScrambleMode.All);
14. OH 框架扩展方法
项目中 OHExtend.cs 提供了针对 Image 的扩展方法,符合 OH 框架的编码规范。
using OHTools;
image.OHFlashWhiteToBlack(duration: 0.5f, isClear: true);
image.OHFlashBlackToWhite(duration: 0.5f, isClear: true);
image.OHGlitchChangeSprite(nextSprite: newSprite, duration: 0.5f);
image.OHFadeChangeSprite(nextSprite: newSprite, duration: 0.5f);
image.OHNeonFlicker(
emissionColor: Color.cyan,
maxFlicker: 1f,
minFlicker: 0.2f,
speed: 4f,
isLoop: true,
totalDuration: 1f
);
image.OHEndEffect(originalMat: null);
15. DOTween 设置和优化
using DG.Tweening;
DOTween.Init(
autoKillMode: AutoKillMode.Default,
useSafeMode: true,
logBehaviour: LogBehaviour.Default
);
DOTween.timeScale = 1f;
DOTween.useUnscaledTime = false;
DOTween.SetTweensCapacity(200, 50);
bool isActive = DOTween.IsTweening(transform);
bool anyActive = DOTween.IsTweening();
List<Tween> activeTweens = DOTween.Totals();
16. 特殊动画类型
using DG.Tweening;
image.DOColor(Color.red, 1f).SetEase(Ease.Linear);
image.DOFade(0f, 1f);
canvasGroup.DOFade(1f, 1f);
text.DOText("New Text", 2f, richTextEnabled: true, scrambleMode: ScrambleMode.None);
Gradient gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(Color.red, 0f), new GradientColorKey(Color.blue, 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
);
material.DOGradientColor(gradient, "_Color", 2f);
Vector3[] path = new Vector3[] {
new Vector3(0, 0, 0),
new Vector3(5, 0, 0),
new Vector3(5, 5, 0),
new Vector3(0, 5, 0)
};
transform.DOPath(path, 4f, PathType.Linear)
.SetLookAt(0.01f)
.SetOptions(closePath: true);
17. DOTween 与 UniTask 集成
项目中已集成 UniTask,DOTween 提供了扩展方法用于异步操作。
using DG.Tweening;
using Cysharp.Threading.Tasks;
async UniTask AsyncExample() {
await transform.DOMoveX(10f, 1f).ToUniTask();
Debug.Log("Move completed");
}
async UniTask SequenceExample() {
Sequence seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10f, 1f));
seq.Append(transform.DOScale(2f, 0.5f));
await seq.Play().ToUniTask();
Debug.Log("Sequence completed");
}
CancellationTokenSource cts = new CancellationTokenSource();
async UniTask CancellableExample() {
try {
await transform.DOMoveX(10f, 1f).WithCancellation(cts.Token);
} catch (OperationCanceledException) {
Debug.Log("Animation cancelled");
}
}
cts.Cancel();
18. 常见使用模式
using DG.Tweening;
void FadeUI(CanvasGroup canvasGroup, bool fadeIn, float duration) {
canvasGroup.DOFade(fadeIn ? 1f : 0f, duration)
.SetEase(Ease.InOutSine)
.OnComplete(() => {
canvasGroup.interactable = fadeIn;
canvasGroup.blocksRaycasts = fadeIn;
});
}
void BounceUI(RectTransform rect) {
rect.DOScale(1.2f, 0.1f)
.SetEase(Ease.OutQuad)
.OnComplete(() => {
rect.DOScale(1f, 0.2f).SetEase(Ease.OutBounce);
});
}
void ButtonClickFeedback(RectTransform button) {
button.DOScale(0.9f, 0.05f)
.SetEase(Ease.OutQuad)
.OnComplete(() => {
button.DOScale(1f, 0.2f).SetEase(Ease.OutBounce);
});
}
void InfiniteRotate(Transform target) {
target.DORotate(new Vector3(0, 360, 0), 2f, RotateMode.WorldAxisAdd)
.SetEase(Ease.Linear)
.SetLoops(-1, LoopType.Restart);
}
void FloatingEffect(Transform target) {
Sequence seq = DOTween.Sequence();
seq.Append(target.DOMoveY(target.position.y + 0.5f, 1f).SetEase(Ease.InOutSine));
seq.Append(target.DOMoveY(target.position.y - 0.5f, 1f).SetEase(Ease.InOutSine));
seq.SetLoops(-1, LoopType.Yoyo);
}
参考文件
此 Skill 包含以下参考资源:
- DOTween Documentation - 官方在线文档
- DOTween 官方示例: 位于
Assets/Plugins/Demigiant/DOTween/ 目录
- OHExtend.cs: 位于
Assets/OH框架工具包/OHExtend.cs - OH 框架扩展方法
项目规范
在使用 DOTween 时,必须遵循以下 OH 框架规范:
-
动画优先级: 除非动画与物理有关,或用户指定要求使用其他插件,否则所有动画都必须使用 DoTween 插件实现。
-
扩展方法优先: 优先检查 OHExtend.cs 中是否已有封装好的方法(如颜色转换、UI 特效)。通用的工具函数应作为 static 扩展方法归入 OHTools 命名空间。
-
命名规范:
- DOTween 扩展方法使用
OH 前缀 (如 OHFlashWhiteToBlack)
- 放置在
OHTools 命名空间下
- 使用中文注释说明方法功能
-
内存优化:
- 使用
SetAutoKill(true) 自动杀死完成的 tween
- 使用
SetRecyclable(true) 允许 tween 被回收
- 在
OnDisable 或 OnDestroy 中杀死对象上的所有 tween
- 避免在
Update 中创建新的 tween
-
生命周期管理:
void OnDisable() {
transform.DOKill();
}
void OnDisable() {
canvasGroup.DOKill();
image.DOKill();
}
-
异常处理:
- 除非用户要求,否则必须避免做出多余的防御性编程操作
- 不添加额外的判空检查、日志打印、异常处理
DOTween vs PrimeTween
项目中同时存在 DOTween 和 PrimeTween 插件。根据架构原则:
- DOTween: 传统的 Unity 动画插件,提供丰富的扩展方法和 OH 框架集成
- PrimeTween: 高性能零分配动画库,适合性能敏感场景
选择建议:
- 使用 DOTween 当需要 OH 框架扩展方法(如
OHGlitchChangeSprite)
- 使用 DOTween 当使用项目已有的 UI 特效系统
- 使用 PrimeTween 当性能是首要考虑因素
- 不要混用两者处理同一对象的动画
最佳实践
- 初始化: 在游戏启动时调用
DOTween.Init()
- 清理: 在场景切换或对象销毁时调用
DOTween.Clear() 或 transform.DOKill()
- 复用: 使用
SetRecyclable(true) 允许 tween 被回收
- 性能: 避免在 Update 中频繁创建 tween
- 调试: 使用
DOTween.Debug.LogBehaviour 控制日志输出
- 序列: 使用
Sequence 组合复杂动画序列
- 缓动: 选择合适的
Ease 类型提升动画质感
- 时间: 使用
SetUpdate(true) 处理暂停/时间缩放场景
DOTween Inspector 面板
在 Unity Editor 中,可通过 Tools/Demigiant/DOTween Utility Panel 打开设置面板,配置:
- 全局设置
- 安全模式
- 时间缩放
- 最大 tween 数量
- 调试选项
此 Skill 基于 DOTween 官方文档 和 OH 框架规范创建。