重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
godot-tweening by thedivergentai/gd-agentic-skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-tweening补间属性动画、缓动曲线、链式调用和生命周期管理共同定义了流畅的程序化运动。
在启动新补间动画前终止活跃补间动画的专家级逻辑,用于防止属性冲突。
使用 set_parallel(true) 和 chain() 实现复杂的多属性 UI 过渡效果。
使用 tween_method 对非属性值(如分数字符串)进行动画处理。
使用可视化的 Curve 资源驱动属性插值,实现自定义缓动效果。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
使用随机循环补间动画实现程序化屏幕抖动效果。
确保当 Engine.time_scale 设置为 0 时,菜单动画仍能继续播放。
使用 tween_subtween 进行分层式过场动画管理,构建可组合的时间线。
使用 as_relative() 和 from_current() 实现动态移动偏移(后坐力/轻微推动)。
使用单个 Tween 对象对一组物品进行顺序动画处理。
创建无限的乒乓式环境效果,以替代繁重的 AnimationPlayer。
Tween.new() 实例化 Tween — 手动创建的 Tween 是无效的。请始终使用 create_tween() 或 get_tree().create_tween() [3, 4]。PropertyTweener 或 CallbackTweener — 这些必须仅由父 Tween 的方法(如 tween_property)生成 [5]。kill() [11, 12]。TRANS_LINEAR 感觉呆板。使用 EASE_OUT + TRANS_QUAD 或 EASE_IN_OUT + TRANS_CUBIC 以获得自然的运动效果 [22]。_process 中不加防护地创建补间动画 — 每秒创建 60 个补间动画会导致应用崩溃。请使用状态检查或终止正在运行的补间动画。bind_node(self) — 如果节点在补间动画运行时被释放,可能会导致错误。绑定可确保补间动画随节点一同终止 [13]。position = goal),以节省开销 [20]。set_parallel(true) 返回后调用 chain() — 如果你想要在并行块之后执行序列动画,必须显式地链接它 [15]。extends Sprite2D
func _ready() -> void:
# 创建补间动画
var tween := create_tween()
# 在 2 秒内对位置进行动画处理
tween.tween_property(self, "position", Vector2(100, 100), 2.0)
# 补间单个属性
var tween := create_tween()
tween.tween_property($Sprite, "modulate:a", 0.0, 1.0) # 淡出
# 链式调用多个补间动画
tween.tween_property($Sprite, "position:x", 200, 1.0)
tween.tween_property($Sprite, "position:y", 100, 0.5)
var tween := create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
tween.tween_callback(func(): print("动画完成!"))
tween.tween_callback(queue_free) # 动画后删除
var tween := create_tween()
tween.tween_property($Label, "modulate:a", 0.0, 0.5)
tween.tween_interval(1.0) # 等待 1 秒
tween.tween_property($Label, "modulate:a", 1.0, 0.5)
var tween := create_tween()
tween.set_ease(Tween.EASE_IN_OUT) # 平滑的开始和结束
tween.set_trans(Tween.TRANS_CUBIC) # 三次方曲线
tween.tween_property($Sprite, "position:x", 200, 1.0)
常用组合:
EASE_IN + TRANS_QUAD: 加速EASE_OUT + TRANS_QUAD: 减速EASE_IN_OUT + TRANS_CUBIC: 平滑的 S 形曲线EASE_OUT + TRANS_BOUNCE: 弹跳效果var tween := create_tween()
tween.set_loops() # 无限循环
tween.tween_property($Sprite, "rotation", TAU, 2.0)
var tween := create_tween()
tween.set_parallel(true)
# 两者同时发生
tween.tween_property($Sprite, "position", Vector2(100, 100), 1.0)
tween.tween_property($Sprite, "scale", Vector2(2, 2), 1.0)
extends Button
func _ready() -> void:
mouse_entered.connect(_on_mouse_entered)
mouse_exited.connect(_on_mouse_exited)
func _on_mouse_entered() -> void:
var tween := create_tween()
tween.tween_property(self, "scale", Vector2(1.1, 1.1), 0.2)
func _on_mouse_exited() -> void:
var tween := create_tween()
tween.tween_property(self, "scale", Vector2.ONE, 0.2)
extends Label
func count_to(target: int, duration: float = 1.0) -> void:
var current := int(text)
var tween := create_tween()
tween.tween_method(
func(value: int): text = str(value),
current,
target,
duration
)
extends Camera2D
@export var follow_speed := 5.0
var target: Node2D
func _process(delta: float) -> void:
if target:
var tween := create_tween()
tween.tween_property(
self,
"global_position",
target.global_position,
1.0 / follow_speed
)
var current_tween: Tween = null
func animate_to(pos: Vector2) -> void:
if current_tween:
current_tween.kill() # 停止之前的动画
current_tween = create_tween()
current_tween.tween_property(self, "position", pos, 1.0)
var tween := create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
tween.finished.connect(_on_tween_finished)
func _on_tween_finished() -> void:
print("动画完成!")
var tween := create_tween()
# 淡出
tween.tween_property($Sprite, "modulate:a", 0.0, 0.5)
# 在不可见时移动
tween.tween_property($Sprite, "position", Vector2(200, 0), 0.0)
# 在新位置淡入
tween.tween_property($Sprite, "modulate:a", 1.0, 0.5)
问题:节点被移除时补间动画停止
# 解决方案:将补间动画绑定到 SceneTree
var tween := get_tree().create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
问题:多个冲突的补间动画
# 解决方案:使用单个补间动画或终止之前的补间动画
# 始终存储引用以便终止旧的补间动画
每周安装量
72
代码仓库
GitHub 星标数
59
首次出现
2026年2月10日
安全审计
安装于
opencode71
codex70
gemini-cli70
kimi-cli69
github-copilot69
amp69
Tween property animation, easing curves, chaining, and lifecycle management define smooth programmatic motion.
Expert logic for killing active tweens before starting new ones to prevent property conflicts.
Using set_parallel(true) and chain() for complex multi-property UI transitions.
Animating non-property values (like score strings) using tween_method.
Driving property interpolation using visual Curve resources for bespoke easing.
Implementing procedural screen shake using randomized looping tweens.
Ensuring menu animations continue playing when Engine.time_scale is set to 0.
Hierarchical cutscene management using tween_subtween for composable timelines.
Using as_relative() and from_current() for dynamic movement offsets (recoil/nudges).
Animating collections of items sequentially using a single Tween object.
Creating infinite ping-pong ambient effects to replace heavy AnimationPlayers.
Tween.new() — Tweens created manually are invalid. Always use create_tween() or get_tree().create_tween() [3, 4].PropertyTweener or CallbackTweener — These must be generated only by the parent Tween methods like tween_property [5].kill() on the old reference first [11, 12].extends Sprite2D
func _ready() -> void:
# Create tween
var tween := create_tween()
# Animate position over 2 seconds
tween.tween_property(self, "position", Vector2(100, 100), 2.0)
# Tween single property
var tween := create_tween()
tween.tween_property($Sprite, "modulate:a", 0.0, 1.0) # Fade out
# Chain multiple tweens
tween.tween_property($Sprite, "position:x", 200, 1.0)
tween.tween_property($Sprite, "position:y", 100, 0.5)
var tween := create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
tween.tween_callback(func(): print("Animation done!"))
tween.tween_callback(queue_free) # Delete after animation
var tween := create_tween()
tween.tween_property($Label, "modulate:a", 0.0, 0.5)
tween.tween_interval(1.0) # Wait 1 second
tween.tween_property($Label, "modulate:a", 1.0, 0.5)
var tween := create_tween()
tween.set_ease(Tween.EASE_IN_OUT) # Smooth start and end
tween.set_trans(Tween.TRANS_CUBIC) # Cubic curve
tween.tween_property($Sprite, "position:x", 200, 1.0)
Common Combinations:
EASE_IN + TRANS_QUAD: AcceleratingEASE_OUT + TRANS_QUAD: DeceleratingEASE_IN_OUT + TRANS_CUBIC: Smooth S-curveEASE_OUT + TRANS_BOUNCE: Bouncy effectvar tween := create_tween()
tween.set_loops() # Infinite loop
tween.tween_property($Sprite, "rotation", TAU, 2.0)
var tween := create_tween()
tween.set_parallel(true)
# Both happen simultaneously
tween.tween_property($Sprite, "position", Vector2(100, 100), 1.0)
tween.tween_property($Sprite, "scale", Vector2(2, 2), 1.0)
extends Button
func _ready() -> void:
mouse_entered.connect(_on_mouse_entered)
mouse_exited.connect(_on_mouse_exited)
func _on_mouse_entered() -> void:
var tween := create_tween()
tween.tween_property(self, "scale", Vector2(1.1, 1.1), 0.2)
func _on_mouse_exited() -> void:
var tween := create_tween()
tween.tween_property(self, "scale", Vector2.ONE, 0.2)
extends Label
func count_to(target: int, duration: float = 1.0) -> void:
var current := int(text)
var tween := create_tween()
tween.tween_method(
func(value: int): text = str(value),
current,
target,
duration
)
extends Camera2D
@export var follow_speed := 5.0
var target: Node2D
func _process(delta: float) -> void:
if target:
var tween := create_tween()
tween.tween_property(
self,
"global_position",
target.global_position,
1.0 / follow_speed
)
var current_tween: Tween = null
func animate_to(pos: Vector2) -> void:
if current_tween:
current_tween.kill() # Stop previous animation
current_tween = create_tween()
current_tween.tween_property(self, "position", pos, 1.0)
var tween := create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
tween.finished.connect(_on_tween_finished)
func _on_tween_finished() -> void:
print("Animation complete!")
var tween := create_tween()
# Fade out
tween.tween_property($Sprite, "modulate:a", 0.0, 0.5)
# Move while invisible
tween.tween_property($Sprite, "position", Vector2(200, 0), 0.0)
# Fade in at new position
tween.tween_property($Sprite, "modulate:a", 1.0, 0.5)
Issue : Tween stops when node is removed
# Solution: Bind tween to SceneTree
var tween := get_tree().create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
Issue : Multiple conflicting tweens
# Solution: Use single tween or kill previous
# Always store reference to kill old tween
Weekly Installs
72
Repository
GitHub Stars
59
First Seen
Feb 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode71
codex70
gemini-cli70
kimi-cli69
github-copilot69
amp69
Go并发编程最佳实践指南:goroutine、channel与同步原语详解
784 周安装
TRANS_LINEAREASE_OUT + TRANS_QUADEASE_IN_OUT + TRANS_CUBIC_process without guards — Creating 60 tweens per second will crash the app. Use a state check or kill the running one.bind_node(self) for non-global tweens — If the node is freed while a tween is running, it can cause errors. Binding ensures it dies with the node [13].position = goal) to save overhead [20].chain() when returning from set_parallel(true) — If you want a sequence after a parallel block, you must explicitly chain it [15].