godot-tweening
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTweening
Tween动画
Tween property animation, easing curves, chaining, and lifecycle management define smooth programmatic motion.
Tween属性动画、缓动曲线、链式动画以及生命周期管理共同构成了流畅的程序化运动效果。
Available Scripts
可用脚本
juice_manager.gd
juice_manager.gd
Expert tween-based juice system with reusable effect presets (bounce, shake, pulse, etc.).
基于Tween的专业视觉增强系统,包含可复用的效果预设(弹跳、震动、脉冲等)。
NEVER Do in Tweening
Tween动画的禁忌
- NEVER create tweens without killing previous — Spam click button, create 100 tweens? Memory leak + conflicting animations. ALWAYS before creating new.
if tween: tween.kill() - NEVER tween in _process without create_tween() — every frame? 60 tweens/second × 60 frames = 3600 tween objects. Create ONCE, reuse OR kill old.
create_tween() - NEVER forget to set_parallel for simultaneous — Chain expecting simultaneous? Sequential by default. Use
tween_property()first.tween.set_parallel(true) - NEVER use 0-duration tweens for instant changes — for teleport? Overhead of tween system. Just set property:
tween_property(x, 0.0).sprite.position = target - NEVER skip finished signal for cleanup — Tween completes, node still references it? Memory held. Connect for cleanup OR null reference.
tween.finished - NEVER use linear interpolation for UI — for button hover? Robotic feel. Use
TRANS_LINEAROREASE_OUT + TRANS_QUADfor organic motion.EASE_IN_OUT + TRANS_CUBIC
gdscript
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)- 绝对不要在未销毁旧补间的情况下创建新补间 — 反复点击按钮会创建100个补间?这会导致内存泄漏和动画冲突。创建新补间前务必执行。
if tween: tween.kill() - 绝对不要在_process中不使用create_tween()就执行补间操作 — 每帧调用?每秒60个补间×60帧=3600个补间对象。应该创建一次后复用,或者销毁旧补间。
create_tween() - 绝对不要忘记设置并行以实现同步动画 — 链式调用却期望同步执行?默认是顺序执行。请先使用
tween_property()。tween.set_parallel(true) - 绝对不要用0时长补间实现即时变更 — 用实现瞬移?这会带来补间系统的额外开销。直接设置属性即可:
tween_property(x, 0.0)。sprite.position = target - 绝对不要忘记通过完成信号进行清理 — 补间完成后,节点仍引用它?这会占用内存。请连接信号进行清理,或者将引用置空。
tween.finished - 绝对不要在UI中使用线性插值 — 按钮悬停效果用?会显得机械生硬。请使用
TRANS_LINEAR或EASE_OUT + TRANS_QUAD实现自然的运动效果。EASE_IN_OUT + TRANS_CUBIC
gdscript
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 Methods
Tween方法
Property Animation
属性动画
gdscript
undefinedgdscript
undefinedTween single property
Tween single property
var tween := create_tween()
tween.tween_property($Sprite, "modulate:a", 0.0, 1.0) # Fade out
var tween := create_tween()
tween.tween_property($Sprite, "modulate:a", 0.0, 1.0) # Fade out
Chain multiple tweens
Chain multiple tweens
tween.tween_property($Sprite, "position:x", 200, 1.0)
tween.tween_property($Sprite, "position:y", 100, 0.5)
undefinedtween.tween_property($Sprite, "position:x", 200, 1.0)
tween.tween_property($Sprite, "position:y", 100, 0.5)
undefinedCallbacks
回调函数
gdscript
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 animationgdscript
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 animationIntervals
时间间隔
gdscript
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)gdscript
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)Easing Functions
缓动函数
gdscript
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:
- : Accelerating
EASE_IN + TRANS_QUAD - : Decelerating
EASE_OUT + TRANS_QUAD - : Smooth S-curve
EASE_IN_OUT + TRANS_CUBIC - : Bouncy effect
EASE_OUT + TRANS_BOUNCE
gdscript
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)常用组合:
- : 加速运动
EASE_IN + TRANS_QUAD - : 减速运动
EASE_OUT + TRANS_QUAD - : 平滑S曲线
EASE_IN_OUT + TRANS_CUBIC - : 弹跳效果
EASE_OUT + TRANS_BOUNCE
Advanced Patterns
高级模式
Looping Animation
循环动画
gdscript
var tween := create_tween()
tween.set_loops() # Infinite loop
tween.tween_property($Sprite, "rotation", TAU, 2.0)gdscript
var tween := create_tween()
tween.set_loops() # Infinite loop
tween.tween_property($Sprite, "rotation", TAU, 2.0)Parallel Tweens
并行补间
gdscript
var tween := create_tween()
tween.set_parallel(true)gdscript
var tween := create_tween()
tween.set_parallel(true)Both happen simultaneously
Both happen simultaneously
tween.tween_property($Sprite, "position", Vector2(100, 100), 1.0)
tween.tween_property($Sprite, "scale", Vector2(2, 2), 1.0)
undefinedtween.tween_property($Sprite, "position", Vector2(100, 100), 1.0)
tween.tween_property($Sprite, "scale", Vector2(2, 2), 1.0)
undefinedUI Button Hover Effect
UI按钮悬停效果
gdscript
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)gdscript
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)Number Counter
数字计数器
gdscript
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
)gdscript
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
)Camera Smooth Follow
相机平滑跟随
gdscript
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
)gdscript
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
)Best Practices
最佳实践
1. Kill Previous Tweens
1. 销毁旧补间
gdscript
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)gdscript
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)2. Use Signals for Completion
2. 使用信号监听完成状态
gdscript
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!")gdscript
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!")3. Chaining for Sequences
3. 链式调用实现序列动画
gdscript
var tween := create_tween()gdscript
var tween := create_tween()Fade out
Fade out
tween.tween_property($Sprite, "modulate:a", 0.0, 0.5)
tween.tween_property($Sprite, "modulate:a", 0.0, 0.5)
Move while invisible
Move while invisible
tween.tween_property($Sprite, "position", Vector2(200, 0), 0.0)
tween.tween_property($Sprite, "position", Vector2(200, 0), 0.0)
Fade in at new position
Fade in at new position
tween.tween_property($Sprite, "modulate:a", 1.0, 0.5)
undefinedtween.tween_property($Sprite, "modulate:a", 1.0, 0.5)
undefinedCommon Gotchas
常见问题
Issue: Tween stops when node is removed
gdscript
undefined问题: 节点被移除时补间停止
gdscript
undefinedSolution: Bind tween to SceneTree
解决方案: 将补间绑定到SceneTree
var tween := get_tree().create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
**Issue**: Multiple conflicting tweens
```gdscriptvar tween := get_tree().create_tween()
tween.tween_property($Sprite, "position", Vector2(100, 0), 1.0)
**问题**: 多个补间冲突
```gdscriptSolution: Use single tween or kill previous
解决方案: 使用单个补间或销毁旧补间
Always store reference to kill old tween
始终保存引用以销毁旧补间
undefinedundefinedReference
参考资料
Related
相关内容
- Master Skill: godot-master
- 核心技能: godot-master