원클릭으로
dotween-unity
DOTween Unity 动画插件。用于补间动画、UI 过渡、相机震动、序列、TextMeshPro 动画以及 Unity 中任何动画需求。此 Skill 应用于 Unity 项目中与 DOTween 动画系统相关的所有任务。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
DOTween Unity 动画插件。用于补间动画、UI 过渡、相机震动、序列、TextMeshPro 动画以及 Unity 中任何动画需求。此 Skill 应用于 Unity 项目中与 DOTween 动画系统相关的所有任务。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Unity Engine 游戏开发。适用于 Unity 项目、C# 脚本、场景设置、GameObject 系统、2D/3D 开发、物理、动画、UI、着色器 Shader、VR/AR 或任何 Unity 相关问题。
MediaPipe Unity Plugin 集成。用于计算机视觉任务、手部/面部/姿态追踪、手势识别、目标检测以及 Unity 中的 ML 解决方案。
PrimeTween Unity 高性能动画库。用于补间动画、UI 过渡、相机震动、序列以及 Unity 中任何零内存分配的动画需求。
创建有效 Skill 的指南。当用户想要创建新 Skill (或更新现有 Skill )以通过专业知识、工作流或工具集成扩展 Claude 能力时,应使用此 Skill 。
| name | doTween-unity |
| description | DOTween Unity 动画插件。用于补间动画、UI 过渡、相机震动、序列、TextMeshPro 动画以及 Unity 中任何动画需求。此 Skill 应用于 Unity 项目中与 DOTween 动画系统相关的所有任务。 |
DOTween (DG.Tweening) 是一个快速、高效、类型安全的 Unity 动画引擎,支持动画所有内容,包括 Transform、UI、Material、颜色、文本等。
在以下情况下触发此 Skill:
using DG.Tweening;
// 位置动画 - 将 transform 移动到目标位置,持续 1 秒
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);
// UI 透明度动画
image.DOFade(0f, 1f);
// 设置缓动和循环
transform.DOMoveX(10, 1f).SetEase(Ease.OutBounce).SetLoops(-1, LoopType.Yoyo);
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);
// 旋转模式 (RotateMode)
// - Fast: 最快的旋转方式 (360° = 0°)
// - FastBeyond360: 允许超过 360°
// - WorldAxisAdd: 在世界轴上旋转增量
// - LocalAxisAdd: 在本地轴上旋转增量
// 均匀缩放
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);
// Punch 效果 (弹性缩放冲击)
transform.DOPunchScale(new Vector3(0.2f, 0.2f, 0.2f), 0.5f, 2, 0.5f);
using DG.Tweening;
using UnityEngine.UI;
// RectTransform 位置和大小
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);
// UI 颜色和透明度
image.DOColor(Color.red, 1f);
image.DOFade(0f, 1f); // 透明度从当前值到目标值
image.DOFade(1f, 1f);
// CanvasGroup 透明度
canvasGroup.DOFade(1f, 0.3f);
// Text 颜色和文本
text.DOColor(Color.yellow, 1f);
text.DOFade(0f, 1f);
text.DOText("Hello World!", 2f, richTextEnabled: true);
// Material 颜色
material.DOColor(Color.blue, 1f);
material.DOColor(Color.white, "_EmissionColor", 1f); // 自定义属性颜色
// Material 透明度
material.DOFade(0f, 1f);
// Material 颜色渐变
material.DOColor(new Color(0, 0, 0, 0), 1f);
// Shader 属性动画
material.DOFloat(1f, "_Metallic", 1f);
material.DOVector(Vector4.one, "_Color", 1f);
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);
// 震动参数说明
// duration: 震动持续时间
// strength: 震动强度 (Vector3)
// vibrato: 震动频率
// randomness: 随机性 (0-180)
// fadeOut: 是否淡出 (默认 true)
using DG.Tweening;
using TMPro;
// TextMeshPro 颜色和透明度
textMeshPro.DOColor(Color.yellow, 1f);
textMeshPro.DOFade(0f, 1f);
// 字体大小
textMeshPro.DOFontSize(48f, 0.5f);
// MaxVisibleCharacters (打字机效果基础)
textMeshPro.DOMaxVisibleCharacters(textMeshPro.textInfo.characterCount, 2f);
// 注意: 项目中 OHExtend.cs 已有打字机效果扩展,但已使用 Text Animator 插件代替
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);
// Punch 效果 (单向冲击,然后回到原值)
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);
using DG.Tweening;
// OnComplete 回调
transform.DOMoveX(10, 1f).OnComplete(() => Debug.Log("Animation completed!"));
// OnUpdate 回调
transform.DOMoveX(10, 1f).OnUpdate(() => Debug.Log("Animating..."));
// OnStart 回调
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"));
using DG.Tweening;
// 无限循环,Yoyo 往返模式
transform.DOMoveY(10, 0.5f).SetLoops(-1, LoopType.Yoyo);
// 指定循环次数
transform.DOScale(2f, 0.5f).SetLoops(3, LoopType.Yoyo);
// LoopType 选项:
// - Restart: 从头重新开始
// - Yoyo: 往返动画
// - Incremental: 每次循环递增 endValue
// 设置循环和缓动
transform.DOMoveX(10, 1f).SetLoops(3, LoopType.Restart).SetEase(Ease.InOutSine);
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));
// 并行动画 (Join)
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));
// 插入动画 (Insert)
seq = DOTween.Sequence();
seq.Append(transform.DOMoveX(10, 1f));
seq.Insert(0.5f, transform.DOScale(2f, 1f)); // 在 0.5 秒处插入
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); // 延迟 1 秒
seq.Append(transform.DOScale(2f, 0.5f));
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);
}
// UniTask 集成 (项目中使用 UniTask)
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");
}
using DG.Tweening;
// 创建并存储 tween 引用
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()}"); // 0-1
Debug.Log($"Elapsed percentage: {tween.ElapsedPercentage()}"); // 0-1
using DG.Tweening;
// 使用标准 Ease
transform.DOMoveX(10, 1f).SetEase(Ease.InOutSine);
transform.DOScale(2f, 0.5f).SetEase(Ease.OutBounce);
image.DOFade(0f, 1f).SetEase(Ease.InQuad);
// 常用 Ease 类型:
// - Linear: 线性
// - InOutSine: 正弦缓入缓出
// - OutBounce: 弹跳效果
// - InQuad: 二次方缓入
// - OutQuad: 二次方缓出
// - InOutQuad: 二次方缓入缓出
// - InCubic, OutCubic, InOutCubic
// - InQuart, OutQuart, InOutQuart
// - InQuint, OutQuint, InOutQuint
// - InExpo, OutExpo, InOutExpo
// - InCirc, OutCirc, InOutCirc
// - InElastic, OutElastic, InOutElastic
// - InBack, OutBack, InOutBack
// - flash: 闪烁效果
// 使用 AnimationCurve
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; // 返回 0-1 的值
});
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); // 使用 unscaled time
// SetRelative: 相对当前值动画
transform.DOLocalMoveX(5, 1f).SetRelative(true); // 从当前位置向右移动 5
// SetUpdate: Update 类型
// - UpdateType.Normal: 使用 Time.deltaTime (默认)
// - UpdateType.Late: 使用 LateUpdate
// - UpdateType.Fixed: 使用 FixedUpdate
// - true: 使用 Time.unscaledDeltaTime (无视 timeScale)
// SetDelay: 开始前延迟
transform.DOMoveX(10, 1f).SetDelay(0.5f); // 延迟 0.5 秒后开始
// SetSpeedBased: 基于速度的动画 (duration 会根据距离自动计算)
transform.DOMove(targetPosition, 1f).SetSpeedBased();
// SetOptions: 特定动画的额外选项
text.DOText("Hello World", 2f).SetOptions(scrambleMode: ScrambleMode.All);
项目中 OHExtend.cs 提供了针对 Image 的扩展方法,符合 OH 框架的编码规范。
using OHTools;
// Image 闪烁效果 (白到黑)
image.OHFlashWhiteToBlack(duration: 0.5f, isClear: true);
// Image 闪烁效果 (黑到白)
image.OHFlashBlackToWhite(duration: 0.5f, isClear: true);
// 故障艺术切换 Sprite
image.OHGlitchChangeSprite(nextSprite: newSprite, duration: 0.5f);
// 渐变切换 Sprite
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);
// 注意: OHTypeWriter 打字机效果已使用 Text Animator 插件代替,不再使用
using DG.Tweening;
// 全局设置
DOTween.Init(
autoKillMode: AutoKillMode.Default, // 自动杀死模式
useSafeMode: true, // 安全模式 (防止单例被销毁时的错误)
logBehaviour: LogBehaviour.Default // 日志行为
);
// TimeScale 控制
DOTween.timeScale = 1f; // 全局时间缩放 (影响所有动画)
DOTween.useUnscaledTime = false; // 是否使用 unscaled time
// 最大同时播放的 tweener 数量 (性能优化)
DOTween.SetTweensCapacity(200, 50);
// 检查是否有活跃的 tween
bool isActive = DOTween.IsTweening(transform);
bool anyActive = DOTween.IsTweening();
// 获取所有活跃的 tweens
List<Tween> activeTweens = DOTween.Totals();
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);
// ScrambleMode 选项:
// - None: 无乱码
// - All: 所有字符
// - Upper: 大写字母
// - Lower: 小写字母
// - Numerals: 数字
// - Custom: 自定义字符集
// 渐变动画
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 数组)
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); // 闭合路径
// PathType 选项:
// - Linear: 直线连接
// - CatmullRom: 平滑曲线 (默认)
项目中已集成 UniTask,DOTween 提供了扩展方法用于异步操作。
using DG.Tweening;
using Cysharp.Threading.Tasks;
// 等待 Tween 完成
async UniTask AsyncExample() {
await transform.DOMoveX(10f, 1f).ToUniTask();
Debug.Log("Move completed");
}
// 等待 Sequence 完成
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();
using DG.Tweening;
// UI 淡入淡出
void FadeUI(CanvasGroup canvasGroup, bool fadeIn, float duration) {
canvasGroup.DOFade(fadeIn ? 1f : 0f, duration)
.SetEase(Ease.InOutSine)
.OnComplete(() => {
canvasGroup.interactable = fadeIn;
canvasGroup.blocksRaycasts = fadeIn;
});
}
// UI 缩放弹跳
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 包含以下参考资源:
Assets/Plugins/Demigiant/DOTween/ 目录Assets/OH框架工具包/OHExtend.cs - OH 框架扩展方法在使用 DOTween 时,必须遵循以下 OH 框架规范:
动画优先级: 除非动画与物理有关,或用户指定要求使用其他插件,否则所有动画都必须使用 DoTween 插件实现。
扩展方法优先: 优先检查 OHExtend.cs 中是否已有封装好的方法(如颜色转换、UI 特效)。通用的工具函数应作为 static 扩展方法归入 OHTools 命名空间。
命名规范:
OH 前缀 (如 OHFlashWhiteToBlack)OHTools 命名空间下内存优化:
SetAutoKill(true) 自动杀死完成的 tweenSetRecyclable(true) 允许 tween 被回收OnDisable 或 OnDestroy 中杀死对象上的所有 tweenUpdate 中创建新的 tween生命周期管理:
// 在 OnDisable 或 OnDestroy 中清理
void OnDisable() {
transform.DOKill(); // 杀死此对象上的所有 tween
}
// 或使用 CanvasGroup/UI 组件
void OnDisable() {
canvasGroup.DOKill();
image.DOKill();
}
异常处理:
项目中同时存在 DOTween 和 PrimeTween 插件。根据架构原则:
选择建议:
OHGlitchChangeSprite)DOTween.Init()DOTween.Clear() 或 transform.DOKill()SetRecyclable(true) 允许 tween 被回收DOTween.Debug.LogBehaviour 控制日志输出Sequence 组合复杂动画序列Ease 类型提升动画质感SetUpdate(true) 处理暂停/时间缩放场景在 Unity Editor 中,可通过 Tools/Demigiant/DOTween Utility Panel 打开设置面板,配置:
此 Skill 基于 DOTween 官方文档 和 OH 框架规范创建。