Tween.tween_property
2026/4/14大约 4 分钟
最后更新日期:2026-04-16
最后同步日期:2026-04-15 | Godot 官方原文 — Tween.tween_property
Tween.tween_property
定义
Tween.tween_property 就像一个"自动渐变遥控器"——你告诉它"把这个属性从 A 变到 B,花多少秒",它就会在指定的时间内,平滑地把属性值从起点变到终点。
打个比方:你家有一个调光台灯,现在亮度是 20%,你想在 3 秒内慢慢调到 100%。你不需要自己一帧一帧地调亮度,只需要告诉它"从 20% 到 100%,3 秒",台灯就会自动平滑过渡。tween_property 就是干这件事的。
在游戏开发中,你经常需要让某个东西"平滑地变化"——角色从 A 点走到 B 点、血条从当前值滑到新值、按钮从透明渐变到不透明——这些都是 tween_property 的用武之地。
函数签名
C#
// Tween.TweenProperty 创建一个属性动画
public Tween TweenProperty(GodotObject obj, NodePath property, Variant finalVal, double duration)GDScript
func tween_property(object: Object, property: NodePath, final_val: Variant, duration: float) -> Tween参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
object | GodotObject / Object | 是 | 要动画的目标对象,比如一个节点、精灵或任意 Godot 对象 |
property | NodePath / StringName | 是 | 要变化的属性路径,如 "position"、"modulate:a"(透明度)、"scale:x" |
final_val | Variant | 是 | 属性的最终值,比如 Vector2(100, 200) 表示位置终点 |
duration | float / double | 是 | 动画持续时间,单位为秒 |
返回值
返回 Tween 对象本身,这样你可以链式调用其他 Tween 方法(如 SetEase、SetTrans)来进一步配置动画。
代码示例
基础用法:让节点平滑移动
C#
using Godot;
public partial class MyScene : Node2D
{
private Sprite2D _sprite;
public override void _Ready()
{
_sprite = GetNode<Sprite2D>("Sprite2D");
// 让精灵在 2 秒内从当前位置移动到 (300, 200)
Tween tween = CreateTween();
tween.TweenProperty(_sprite, "position", new Vector2(300, 200), 2.0);
// 运行结果: 精灵会花 2 秒平滑地从当前位置移动到 (300, 200)
}
}GDScript
extends Node2D
@onready var sprite = $Sprite2D
func _ready():
# 让精灵在 2 秒内从当前位置移动到 (300, 200)
var tween = create_tween()
tween.tween_property(sprite, "position", Vector2(300, 200), 2.0)
# 运行结果: 精灵会花 2 秒平滑地从当前位置移动到 (300, 200)链式调用:移动 + 缩放 + 透明度渐变
C#
using Godot;
public partial class MyScene : Node2D
{
private Sprite2D _sprite;
public override void _Ready()
{
_sprite = GetNode<Sprite2D>("Sprite2D");
_sprite.Position = new Vector2(100, 100);
_sprite.Scale = new Vector2(1, 1);
_sprite.Modulate = new Color(1, 1, 1, 1);
Tween tween = CreateTween();
// 先花 1 秒移动到右侧
tween.TweenProperty(_sprite, "position", new Vector2(400, 100), 1.0);
// 然后花 0.5 秒放大到 2 倍
tween.TweenProperty(_sprite, "scale", new Vector2(2, 2), 0.5);
// 最后花 0.5 秒淡出(透明度变 0)
tween.TweenProperty(_sprite, "modulate:a", 0.0, 0.5);
// 运行结果: 精灵先移动(1秒) → 再放大(0.5秒) → 再消失(0.5秒),总共 2 秒
}
}GDScript
extends Node2D
@onready var sprite = $Sprite2D
func _ready():
sprite.position = Vector2(100, 100)
sprite.scale = Vector2(1, 1)
sprite.modulate = Color(1, 1, 1, 1)
var tween = create_tween()
# 先花 1 秒移动到右侧
tween.tween_property(sprite, "position", Vector2(400, 100), 1.0)
# 然后花 0.5 秒放大到 2 倍
tween.tween_property(sprite, "scale", Vector2(2, 2), 0.5)
# 最后花 0.5 秒淡出(透明度变 0)
tween.tween_property(sprite, "modulate:a", 0.0, 0.5)
# 运行结果: 精灵先移动(1秒) → 再放大(0.5秒) → 再消失(0.5秒),总共 2 秒实际场景:血条平滑减少
C#
using Godot;
public partial class HealthBar : Control
{
[Export] public float ExMaxHealth = 100.0f;
private ColorRect _fillRect;
private float _currentHealth;
public override void _Ready()
{
_fillRect = GetNode<ColorRect>("Fill");
_currentHealth = ExMaxHealth;
_UpdateBar();
}
public void TakeDamage(float amount)
{
_currentHealth = Mathf.Max(0, _currentHealth - amount);
// 血条在 0.3 秒内平滑收缩到新值
Tween tween = CreateTween();
float targetWidth = (_currentHealth / ExMaxHealth) * 200.0f;
tween.TweenProperty(_fillRect, "size:x", targetWidth, 0.3);
// 运行结果: 受到伤害后,血条会在 0.3 秒内平滑地缩短到对应长度
GD.Print($"当前血量: {_currentHealth}");
// 运行结果: 当前血量: 70(假设受到 30 点伤害)
}
private void _UpdateBar()
{
_fillRect.Size = new Vector2((_currentHealth / ExMaxHealth) * 200.0f, 20.0f);
}
}GDScript
extends Control
@export var max_health: float = 100.0
@onready var fill_rect = $Fill
var _current_health: float
func _ready():
_current_health = max_health
_update_bar()
func take_damage(amount: float):
_current_health = max(0, _current_health - amount)
# 血条在 0.3 秒内平滑收缩到新值
var tween = create_tween()
var target_width = (_current_health / max_health) * 200.0
tween.tween_property(fill_rect, "size:x", target_width, 0.3)
# 运行结果: 受到伤害后,血条会在 0.3 秒内平滑地缩短到对应长度
print("当前血量: ", _current_health)
# 运行结果: 当前血量: 70.0(假设受到 30 点伤害)
func _update_bar():
fill_rect.size = Vector2((_current_health / max_health) * 200.0, 20.0)注意事项
- 链式调用的执行顺序:默认情况下,多个
TweenProperty链式调用是顺序执行的(一个结束后才开始下一个)。如果你想让它们同时执行,可以使用SetParallel()。 - 属性路径支持子属性:可以用冒号访问嵌套属性,比如
"position:x"只改 X 坐标,"modulate:a"只改透明度。 - 对象被释放会导致问题:如果目标对象在动画播放期间被销毁(比如调用了
QueueFree()),动画会自动停止,不会报错。 - 不要在
_Process中反复创建:CreateTween()每次调用都创建新的 Tween 对象,如果每帧都创建,会导致大量未完成的动画叠加。通常在事件触发时(如按键、受伤)创建一次即可。
