Godot 4 补间动画 (Tween) 指北

J.sky
1062 字 · 预计阅读 6 min read
2026/1/18

为什么选择 Tween?

Godot 4 带来的全新 Tween 系统,摒弃了传统的节点式操作,改用全代码驱动,更加简洁且强大。

Tween:适合程序化、动态的 UI 反馈、物品掉落、数值平滑变化(纯代码控制)。

核心语法

创建一个最基本的平移动画:

var tween = create_tween()
tween.tween_property($Sprite2D, "position", Vector2(600, 300), 1.0)

只需两行,对象就会在 1 秒内平滑移动到目标位置。

让动画有灵魂:Transition 与 Ease

  1. set_trans():过渡类型 (TransitionType) 这是最核心的参数,决定了动画的“性格”。
枚举常量 (Tween.TransitionType)动画效果描述最佳用途
TRANS_LINEAR匀速。没有任何加减速。简单的旋转、血条数值变化。
TRANS_SINE正弦。非常柔和的加速减速。缓慢漂浮、呼吸灯效果。
TRANS_QUAD二次方。基础的加减速。最常用的平滑移动。
TRANS_CUBIC三次方。比 Quad 更明显的加减速。强调动作起伏。
TRANS_QUART四次方。加速感更强。快速切入/切出。
TRANS_EXPO指数级。极端的加减速。闪电般的瞬间移动。
TRANS_ELASTIC弹性。像皮筋拉伸后的回弹。Q弹的按钮、果冻物体。
TRANS_BOUNCE反弹。像球落地后的弹跳。物理掉落效果、菜单撞击边缘。
TRANS_BACK回退。先往后拉一点再冲出去。蓄力感的动作、浮窗弹出。
TRANS_SPRING弹簧。真实的物理弹簧震荡。Godot 4 新增,比 Elastic 更自然。
  1. set_ease():缓动模式 (EaseType)这个参数决定了上面选定的曲线如何应用在时间轴上。
枚举常量 (Tween.EaseType)逻辑描述视觉表现
EASE_IN入场加速。动画开始时很慢,然后加速。常用于离开屏幕。
EASE_OUT出场减速。动画开始时很快,快结束时减慢。UI 动画最常用。
EASE_IN_OUT两头慢中间快。开始和结束都有缓冲。适合循环往复的动作。
EASE_OUT_IN两头快中间慢。较少使用。
  1. 黄金组合建议 如果你不知道该选什么,可以尝试这些经过验证的经典组合:
  • 自然的 UI 弹出: set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)

  • 丝滑的淡入淡出: set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)

  • 有打击感的移动: set_trans(Tween.TRANS_QUART).set_ease(Tween.EASE_OUT)

  • 极度夸张的点击反馈: set_trans(Tween.TRANS_ELASTIC).set_ease(Tween.EASE_OUT)

动态演示

你可以将下面的脚本挂载到一个空的 Node2D 场景中。运行后,它会生成一排图标,演示各种常见的 Tween 曲线。

extends Node2D

# 使用 Godot 的默认图标作为演示物体
var icon_texture = preload("res://icon.svg")

# 定义我们要演示的配置组合
var setups = [
    {"name": "Linear", "trans": Tween.TRANS_LINEAR, "ease": Tween.EASE_IN_OUT},
    {"name": "Sine Out", "trans": Tween.TRANS_SINE, "ease": Tween.EASE_OUT},
    {"name": "Back Out", "trans": Tween.TRANS_BACK, "ease": Tween.EASE_OUT},
    {"name": "Bounce Out", "trans": Tween.TRANS_BOUNCE, "ease": Tween.EASE_OUT},
    {"name": "Elastic Out", "trans": Tween.TRANS_ELASTIC, "ease": Tween.EASE_OUT},
    {"name": "Quint In", "trans": Tween.TRANS_QUINT, "ease": Tween.EASE_IN}
]

func _ready():
    # 为每种配置创建一个演示行
    for i in range(setups.size()):
        create_demo_row(i, setups[i])

func create_demo_row(index, config):
    # 1. 创建并添加精灵
    var sprite = Sprite2D.new()
    sprite.texture = icon_texture
    sprite.scale = Vector2(0.5, 0.5)
    sprite.position = Vector2(100, 100 + index * 100)
    add_child(sprite)
    
    # 2. 创建并添加标签文字
    var label = Label.new()
    label.text = config["name"]
    label.position = Vector2(20, 70 + index * 100)
    add_child(label)
    
    # 3. 启动循环动画函数
    animate_sprite(sprite, config)

func animate_sprite(sprite, config):
    var start_pos = Vector2(100, sprite.position.y)
    var end_pos = Vector2(1000, sprite.position.y)
    
    # 创建 Tween
    var tween = create_tween().set_loops() # 无限循环
    
    # 设置当前行的过渡和缓动参数
    tween.set_trans(config["trans"])
    tween.set_ease(config["ease"])
    
    # 动画序列:移动到右边 -> 等待 -> 瞬移回左边
    tween.tween_property(sprite, "position", end_pos, 2.0)
    tween.tween_interval(0.5)
    tween.tween_property(sprite, "position", start_pos, 0.0) # 瞬移回起始点
    tween.tween_interval(0.5)

运行游戏后的效果:

效果图

这段代码展示了几个关键技巧:

  • set_loops(): 让动画自动重复。注意在 Godot 4 中,不带参数的 set_loops() 表示无限循环。

  • tween_interval(): 在往返运动之间加入停顿,方便观察终点的回弹或碰撞效果。

  • 瞬移技巧: 将 duration 设置为 0.0 的 tween_property 可以当作“瞬间改变属性”来使用。

  • 动态组合: 你可以轻松地在 setups 数组里添加更多组合,比如对比 EASE_IN 和 EASE_OUT 的区别。

总结与建议

UI 弹出:首选 TRANS_BACK + EASE_OUT。

打击感:试试 TRANS_QUINT 或 TRANS_EXPO。

生命周期:不需要手动 queue_free(),Tween 运行完会自动消失。

中断处理:如果需要在动画中途停止,可以调用 tween.kill()。

本文为原创文章,遵循: CC BY-NC-SA 4.0版权协议,转载请附上原文出处链接和本声明。

英雄请留步!欢迎在下方留言交流!

那年今日