关于 godot-tweening
面向 Godot 开发者的 Tween 技能,用于选择和管理程序化运动、UI 效果及定时序列。它说明何时使用 Tween 或 AnimationPlayer,并提供安全中断、暂停时 UI 动画和物理同步运动的模式。
主要功能
- 01Tween 与 AnimationPlayer 的选择指引
- 02安全中断并重新创建
- 03时间缩放为零时的暂停菜单动画
- 04并行与串联动画序列
- 05物理同步的属性运动
- 06基于曲线的缓动与运动
适用场景
- 01制作 UI 弹窗和分数计数动画
- 02安全重启可重复触发的动画
- 03游戏暂停时播放暂停菜单动画
- 04串联过场或库存界面效果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-tweening安装后在 Claude Code 中输入/godot-tweening确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/migration-notes.mdtween-recipes-and-gotchas.mdscripts/camera_shake_tween_logic.gdcustom_curve_tween.gdjuice_manager.gdlooped_hover_vfx.gdnested_subtween_cutscene.gdparallel_popup_animation.gdrelative_recoil_tween.gdsafe_tween_interruption.gdstaggered_inventory_entry.gdtext_counter_method_tween.gdtime_scale_ignored_ui.gdtween_builder.gd详细介绍
决策树 — Tween 还是 AnimationPlayer
| 情况 | 选择 |
|---|---|
| 一次性的 UI 动效、悬停、弹出、分数计数、后坐力 | Tween(create_tween) |
| 编写好的多轨剪辑、可拖动时间轴、混合树 | AnimationPlayer / AnimationTree |
| 镜头持续跟随移动目标 | Camera2D.position_smoothing / 弹簧跟随 — 不要在每次 _process 中新建 Tween |
Engine.time_scale == 0 时的菜单动画 | 使用 set_ignore_time_scale(true) 的 Tween — 必须 time_scale_ignored_ui.gd |
| 可重新触发的属性(连续点击按钮、闪避取消) | 创建前先终止 — 必须 safe_tween_interruption.gd |
| 物理体 / 网络校正移动 | TWEEN_PROCESS_PHYSICS + reset_physics_interpolation |
可用脚本
必须:编写 Tween 代码前,先阅读上面对应情况的脚本。
safe_tween_interruption.gd
任何可重新触发的 Tween 都必须使用 — 启动新 Tween 前,先终止活动中的 Tween。
time_scale_ignored_ui.gd
暂停菜单 / time_scale == 0 时的 UI 动画必须使用。
nested_subtween_cutscene.gd
通过 tween_subtween 组合过场动画时间轴时必须使用。
parallel_popup_animation.gd
使用 set_parallel(true) + chain() 实现多属性 UI 转场。
text_counter_method_tween.gd
对非属性值(分数字符串)使用 tween_method。
custom_curve_tween.gd
使用 Curve 资源实现自定义缓动。
camera_shake_tween_logic.gd
使用循环 Tween 实现程序化屏幕抖动(偏移,而非跟随)。
relative_recoil_tween.gd
使用 as_relative() / from_current() 实现后坐力微调。
staggered_inventory_entry.gd
在一个 Tween 上依次播放物品入场动画。
looped_hover_vfx.gd
无限循环的乒乓式环境动效。
juice_manager.gd / tween_builder.gd
当多个系统共用动效预设时,用于集中调度动效 / 提供构建器辅助方法。
Tween 动画中绝对不要这样做
- 绝不要使用
Tween.new()实例化 Tween — 始终使用create_tween()或get_tree().create_tween()[3, 4]。 - 绝不要尝试复用已结束的 Tween — Tween 只能使用一次;要重播就重新创建 [4]。
- 绝不要手动实例化
PropertyTweener或CallbackTweener— 只能通过父级 Tween 方法创建 [5]。 - 绝不要创建只包含 0 时长动画的无限循环 — 这会使引擎冻结 [10]。
- 绝不要用多个 Tween 同时动画化同一属性 — 先用
kill()终止旧引用 [11, 12]。 - 绝不要对 UI / 动效使用线性插值 — 优先使用
EASE_OUT + TRANS_QUAD或EASE_IN_OUT + TRANS_CUBIC[22]。 - 绝不要在
_process中不加保护地创建 Tween — 每秒创建 60 个 Tween 会导致应用崩溃。 - 非全局 Tween 绝不要跳过
bind_node(self)— 绑定后,节点销毁时 Tween 也会销毁 [13]。 - 绝不要用 0 时长 Tween 改变状态 — 直接设置属性 [20]。
- 从
set_parallel(true)切回顺序执行时,绝不要忘记调用chain()[15]。
生命周期黄金路径
var _tween: Tween
func animate_to(pos: Vector2) -> void:
if _tween and _tween.is_valid():
_tween.kill()
_tween = create_tween().bind_node(self)
_tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUAD)
_tween.tween_property(self, "position", pos, 0.35)
必须遵循的模式来源: safe_tween_interruption.gd。
镜头跟随(正确做法)
持续跟随不是 Tween 的工作:
extends Camera2D
@export var target: Node2D
func _ready() -> void:
position_smoothing_enabled = true
position_smoothing_speed = 5.0
func _physics_process(_delta: float) -> void:
if target:
global_position = target.global_position
如果必须让镜头执行一次性冲击 / 返回动画,请保留一个 Tween 引用,并在重新创建前先终止旧 Tween — 绝不要在未加保护的 _process 中调用 create_tween()。
专家模式(保留)
Physics-Sync-Tweening
func apply_physics_tween(target: Node3D, start_pos: Vector3, goal: Vector3) -> void:
target.global_position = start_pos
target.reset_physics_interpolation()
var tween := create_tween().bind_node(target)
tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
tween.tween_property(target, "global_position", goal, 0.5)
Juice-Config-Resource
将持续时间 / 转场 / 缓动存储在 Resource 中(参见动效脚本),让动效效果由数据驱动。
Tween-Event-Sequencing
并行块 → chain() → 间隔/回调 → 退出。对于嵌套模块,优先使用 nested_subtween_cutscene.gd。
Bezier-Path-Tween
对 PathFollow2D.progress_ratio 执行动画补间,而不是手动编写 Bezier 数学计算。
深入用法(按需查阅)
LLM 忽略规则:如果通用 Agent 在阅读之前不会知道某项内容,那么它就属于这里或
scripts/中——绝不要删除,只需移动。
| 主题 | 参考资料 |
|---|---|
| 链式调用、终止、注意事项 | tween-recipes-and-gotchas.md |
参考资料
渐进式披露:仅在研究特定 API 时打开官方文档链接;在切换到相关领域时加载相关技能——不要预加载整个技能网络。
官方文档
- Tween — create_tween、并行/链式调用、循环、处理模式、ignore_time_scale 和终止/生命周期规则。
- PropertyTweener — tween_property 详情:as_relative、from_current、自定义插值器,以及每个步骤的缓动/过渡。
- MethodTweener — 对非属性值使用 tween_method(例如分数计数器、着色器参数、通过 Curve 采样的运动)。
- CallbackTweener — 使用 tween_callback 实现有序副作用,无需臆造持续时间为 0 的属性步骤。
- IntervalTweener — tween_interval 在单个 Tween 时间线上添加延迟。
- SubtweenTweener — 使用 tween_subtween 将过场动画模块嵌套在同一父级时间线下。
- 插值 — 介绍缓动选择和自定义插值器背后的 lerp/smoothstep 基础知识。
- Bezier、曲线和路径 — 当仅靠属性补间无法描述路径时使用的 Curve/PathFollow 模式。
- 动画功能简介 — 了解何时 Tween 已足够,何时应使用 AnimationPlayer/AnimationTree 编辑轨道。
- 使用 SceneTree — bind_node 不够用时,了解 SceneTree.create_tween 和节点生命周期。
- 空闲与物理处理 — 了解 TWEEN_PROCESS_PHYSICS 同步所需的空闲与物理处理模式。
- 物理插值快速入门指南 — 对启用了插值的物体执行变换补间时使用 reset_physics_interpolation。
相关技能
前置要求
- godot-project-foundations — 在学习 create_tween/bind_node 生命周期模式之前,先了解场景树、Node 所有权和资源基础知识。
- godot-gdscript-mastery — 了解 tween_method 和 finished 处理器中使用的类型化 callable、lambda 以及 await/信号惯用写法。
配套内容
- godot-2d-animation — 精灵/骨骼动画通常会与 Tween 动效配合使用,并需要遵循统一的销毁/生命周期管理规范。
- godot-animation-player — 复杂时间线使用预设动画片段;Tween 则用于运行时/程序化 UI 和一次性动效。
- godot-ui-containers — Control 的大小/枢轴/布局背景知识,有助于制作弹出窗口的缩放淡入效果和错开播放的库存入场 Tween。
- godot-signal-architecture — 在 Tween 被销毁并重新创建时,确保 finished/回调连接不会悬空。
- godot-camera-systems — 通过程序化 Tween 驱动镜头跟随、震动偏移和注视目标。
- godot-resource-data-patterns — 使用 JuiceConfig 风格的 Resource,在游戏脚本外存储时长/trans/ease。
- godot-particles — 爆发时序和一次性 VFX 应从 tween_callback 步骤启动,而不是使用并行的临时计时器。
- godot-shaders-basics — 当属性路径无法满足需求时,通过 tween_method / set 为着色器参数添加动画。
下游/使用方
- godot-inventory-system — 基于错开播放且可中断的 Tween,制作槽位/物品入场、拖动反馈和装备动效。
- godot-genre-card-game — 手牌弧线、抽牌/弃牌飞行动画和结算润色都依赖 Tween 串联。
- godot-ui-theming — 由主题驱动的悬停/焦点动画,在同一个 Control 下仍需要安全地中断 Tween。
主模块
- godot-master — 用于跨技能发现的库路由器和镜像模块入口。