preload
2026/4/14大约 3 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — preload
preload
定义
preload() 用于在脚本编译时就加载资源文件。和 load() 的区别在于加载时机:
preload()在脚本加载时就完成资源读取,游戏运行时直接使用,没有任何延迟load()在代码执行到那一行时才加载,可能有短暂的等待
preload() 的路径必须是字符串常量——你不能用变量或拼接的字符串,因为在编译时 Godot 需要知道确切的文件路径。
函数签名
C#
// C# 中没有直接等价的 preload
// 推荐在类级别使用 GD.Load 进行延迟加载
private readonly Resource _texture = GD.Load<Texture2D>("res://icon.svg");GDScript
# 路径必须是字符串常量
const TEXTURE = preload("res://icon.svg")参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
path | String(必须是常量) | 是 | 资源文件的路径,必须是字符串字面量,不能使用变量或拼接 |
返回值
Variant(通常是 Resource 的子类)—— 加载的资源对象。由于在编译时就加载了,返回值不可能为 null(如果路径有误,编辑器会报错提示)。
代码示例
基础用法:编译时加载资源
C#
using Godot;
public partial class PreloadExample : Node
{
// C# 没有编译时加载,使用类字段在首次访问时加载
private static readonly Texture2D PlayerTexture = GD.Load<Texture2D>("res://assets/player.png");
public override void _Ready()
{
var sprite = new Sprite2D();
sprite.Texture = PlayerTexture;
AddChild(sprite);
GD.Print("玩家图片已加载");
}
}GDScript
extends Node
# 在脚本顶部用 preload 预加载资源
var player_texture = preload("res://assets/player.png")
var bullet_scene = preload("res://scenes/bullet.tscn")
var shoot_sound = preload("res://sounds/shoot.ogg")
func _ready():
var sprite = Sprite2D.new()
sprite.texture = player_texture
add_child(sprite)
print("玩家图片已加载")实际场景:子弹发射系统
C#
using Godot;
public partial class Gun : Node2D
{
// 预加载子弹场景
private static readonly PackedScene BulletScene = GD.Load<PackedScene>("res://scenes/bullet.tscn");
[Export] public float ExBulletSpeed = 500f;
public void Fire()
{
var bullet = BulletScene.Instantiate<Node2D>();
GetTree().CurrentScene.AddChild(bullet);
bullet.GlobalPosition = GlobalPosition;
GD.Print($"发射子弹,速度: {ExBulletSpeed}");
}
public override void _Ready()
{
Fire();
// 运行结果: 发射子弹,速度: 500
}
}GDScript
extends Node2D
# 预加载子弹场景:在脚本加载时就准备好,发射时无需等待
var bullet_scene = preload("res://scenes/bullet.tscn")
@export var ex_bullet_speed: float = 500.0
func fire() -> void:
var bullet = bullet_scene.instantiate()
get_tree().current_scene.add_child(bullet)
bullet.global_position = global_position
print("发射子弹,速度: ", ex_bullet_speed)
func _ready():
fire()
# 运行结果: 发射子弹,速度: 500.0进阶用法:音频管理器
C#
using Godot;
using System.Collections.Generic;
public partial class AudioManager : Node
{
public static readonly AudioStream SfxJump = GD.Load<AudioStream>("res://sounds/jump.ogg");
public static readonly AudioStream SfxCoin = GD.Load<AudioStream>("res://sounds/coin.ogg");
public static readonly AudioStream SfxHit = GD.Load<AudioStream>("res://sounds/hit.ogg");
private readonly Dictionary<AudioStream, AudioStreamPlayer> _players = new();
public void Play(AudioStream stream)
{
if (stream == null) return;
var player = new AudioStreamPlayer();
player.Stream = stream;
AddChild(player);
player.Play();
player.Finished += () => player.QueueFree();
}
public override void _Ready()
{
Play(SfxJump);
GD.Print("播放跳跃音效");
}
}GDScript
extends Node
# 预加载所有常用音效:在脚本加载时一次性完成
var sfx_jump = preload("res://sounds/jump.ogg")
var sfx_coin = preload("res://sounds/coin.ogg")
var sfx_hit = preload("res://sounds/hit.ogg")
func play(stream: AudioStream) -> void:
if stream == null:
return
var player = AudioStreamPlayer.new()
player.stream = stream
add_child(player)
player.play()
player.finished.connect(func(): player.queue_free())
func _ready():
play(sfx_jump)
print("播放跳跃音效")注意事项
路径必须是常量:
preload("res://" + variable)是不允许的——会报错。如果你需要动态拼接路径,必须使用load()。编辑器会检查路径:如果
preload()的路径不存在,编辑器会在编译时报错并高亮显示,而不是等到运行时才发现问题。这是preload()的一个优势。与
load()的性能差异:preload()在脚本加载时完成,运行时直接使用缓存,没有任何延迟。load()在执行时才加载,首次调用可能有短暂等待。对于频繁使用的资源(如子弹场景、常用音效),推荐使用preload()。C# 中没有直接等价:C# 中没有
preload关键字。推荐使用GD.Load<T>()在类字段初始化时加载,效果类似但不完全相同(C# 的加载发生在类首次使用时而非编译时)。
