@onready
2026/4/14大约 3 分钟
最后更新日期:2026-04-16
最后同步日期:2026-04-15 | Godot 官方原文 — @onready
@onready
定义
@onready 是 GDScript 中的一个注解(annotation),用来延迟变量的初始化——让变量的赋值等到节点进入场景树之后才执行。简单说,就是告诉 Godot:"这个变量别着急赋值,等节点准备好了再初始化。"
为什么需要这个?因为在 GDScript 中,脚本加载时节点可能还没进入场景树。如果你直接写 var sprite = $Sprite2D,这时候 $Sprite2D 可能还不存在(因为节点还没加进来),就会报错。加了 @onready,Godot 会在 _ready() 函数被调用之前帮你完成赋值,此时节点已经在场景树中了。
在 C# 中,没有直接等价的注解。对应的做法是在 _Ready() 方法中手动赋值。
语法
C#
// C# 中在 _Ready() 方法中手动赋值
private Sprite2D _sprite;
private AudioStreamPlayer _audioPlayer;
public override void _Ready()
{
_sprite = GetNode<Sprite2D>("Sprite2D");
_audioPlayer = GetNode<AudioStreamPlayer>("AudioStreamPlayer");
}GDScript
# 使用 @onready 延迟初始化
@onready var _sprite: Sprite2D = $Sprite2D
@onready var _audio_player: AudioStreamPlayer = $AudioStreamPlayer
# 也可以和 @export 一起使用
@export var ex_speed: float = 200.0
@onready var _rigid_body: RigidBody3D = $RigidBody3D参数说明
@onready 不需要任何参数——它直接写在变量声明前面即可。
| 说明项 | 详情 |
|---|---|
| 适用类型 | 任何类型,通常用于节点引用(通过 $ 或 get_node()) |
| 初始化时机 | 在 _ready() 被调用之前执行(此时节点已进入场景树) |
| 常用写法 | @onready var _node = $NodeName |
返回值
@onready 是一个注解,没有返回值。它的作用是改变变量的初始化时机,让赋值延迟到节点就绪后执行。
代码示例
C#
using Godot;
public partial class Player : CharacterBody3D
{
// ===== 基础用法:在 _Ready() 中初始化节点引用 =====
private Sprite3D _sprite;
private AudioStreamPlayer _audioPlayer;
private CollisionShape3D _collisionShape;
public override void _Ready()
{
_sprite = GetNode<Sprite3D>("Sprite3D");
_audioPlayer = GetNode<AudioStreamPlayer>("AudioStreamPlayer");
_collisionShape = GetNode<CollisionShape3D>("CollisionShape3D");
GD.Print($"精灵可见: {_sprite.Visible}");
}
// 运行结果: 精灵可见: True
// ===== 实际场景:获取子节点并配置 =====
[Export] public float ExMoveSpeed = 200f;
[Export] public float ExJumpForce = 400f;
private AnimationPlayer _animPlayer;
private Camera3D _camera;
public override void _Ready()
{
_animPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
_camera = GetNode<Camera3D>("Camera3D");
_animPlayer.Play("idle");
_camera.Current = true;
GD.Print($"动画播放: {_animPlayer.CurrentAnimation},相机激活: {_camera.Current}");
}
// 运行结果: 动画播放: idle,相机激活: True
// ===== 进阶用法:链式调用与路径引用 =====
[Export] public PackedScene ExBulletScene;
private Marker3D _spawnPoint;
private Timer _fireTimer;
private Label _healthLabel;
public override void _Ready()
{
_spawnPoint = GetNode<Marker3D>("Gun/SpawnPoint");
_fireTimer = GetNode<Timer>("FireTimer");
_healthLabel = GetNode<Label>("HUD/HealthLabel");
_fireTimer.Timeout += OnFireTimerTimeout;
UpdateHealthLabel(100);
GD.Print($"开火点位置: {_spawnPoint.Position}");
}
private void OnFireTimerTimeout()
{
GD.Print("开火计时器触发");
}
private void UpdateHealthLabel(int health)
{
_healthLabel.Text = $"HP: {health}";
GD.Print($"生命标签: {_healthLabel.Text}");
}
// 运行结果: 开火点位置: (0, 0.5, -1)
// 运行结果: 生命标签: HP: 100
}GDScript
extends CharacterBody3D
# ===== 基础用法:@onready 延迟初始化 =====
@onready var _sprite: Sprite3D = $Sprite3D
@onready var _audio_player: AudioStreamPlayer = $AudioStreamPlayer
@onready var _collision_shape: CollisionShape3D = $CollisionShape3D
func _ready():
print("精灵可见: %s" % _sprite.visible)
# 运行结果: 精灵可见: True
# ===== 实际场景:获取子节点并配置 =====
@export var ex_move_speed: float = 200.0
@export var ex_jump_force: float = 400.0
@onready var _anim_player: AnimationPlayer = $AnimationPlayer
@onready var _camera: Camera3D = $Camera3D
func _ready():
_anim_player.play("idle")
_camera.current = true
print("动画播放: %s,相机激活: %s" % [_anim_player.current_animation, _camera.current])
# 运行结果: 动画播放: idle,相机激活: True
# ===== 进阶用法:链式路径与信号连接 =====
@export var ex_bullet_scene: PackedScene
@onready var _spawn_point: Marker3D = $Gun/SpawnPoint
@onready var _fire_timer: Timer = $FireTimer
@onready var _health_label: Label = $HUD/HealthLabel
func _ready():
_fire_timer.timeout.connect(_on_fire_timer_timeout)
update_health_label(100)
print("开火点位置: %s" % _spawn_point.position)
func _on_fire_timer_timeout():
print("开火计时器触发")
func update_health_label(health: int):
_health_label.text = "HP: %d" % health
print("生命标签: %s" % _health_label.text)
# 运行结果: 开火点位置: (0, 0.5, -1)
# 运行结果: 生命标签: HP: 100注意事项
@onready是 GDScript 独有的特性,C# 中没有等价的注解。C# 中需要在_Ready()方法中手动调用GetNode<T>()来获取节点引用。@onready的变量会在_ready()之前被初始化。所以在_ready()中可以安全地使用这些变量。- 如果引用的节点路径不存在,
@onready初始化时会报错。确保路径正确。 @onready常与$语法搭配使用(如@onready var _node = $NodeName),也可以与get_node()或get_parent()等方法搭配。@onready和@export可以同时使用:@export var ex_speed = 200.0; @onready var _body = $Body。- 如果你在
_ready()中重新赋值了@onready变量,新值会覆盖自动初始化的值。
