资源管理

资源管理

Godot 的资源系统用于管理可重用的游戏资源。

资源类型

纹理 (Texture)

# 加载纹理
var texture = preload("res://images/icon.png")
var texture2 = load("res://images/icon.png")

# 动态加载(运行时)
var dynamic_texture = load("user://saved_texture.png")

# 在节点中使用
$Sprite2D.texture = texture

# AtlasTexture(图集纹理)
var atlas = AtlasTexture.new()
atlas.atlas = preload("res://atlas.png")
atlas.region = Rect2(0, 0, 32, 32)

字体 (Font)

# 使用系统字体
var label = Label.new()
label.add_theme_font_override("font", ThemeDB.fallback_font)

# 使用自定义字体
var custom_font = preload("res://fonts/my_font.tres")
label.add_theme_font_override("font", custom_font)

音频 (Audio)

# 加载音频流
var bgm = preload("res://audio/background_music.ogg")
var sfx = preload("res://audio/jump.wav")

# 播放音频
@onready var audio_player = $AudioStreamPlayer
audio_player.stream = bgm
audio_player.play()

# 音频总线(AudioBus)
# 项目设置 -> Audio -> Bus 添加总线
AudioServer.set_bus_volume_db(0, linear_to_db(0.8))  # 80% 音量

脚本 (Script)

# 加载脚本
var player_script = preload("res://scripts/Player.gd")

# 动态设置脚本
player.set_script(player_script)

场景 (Scene)

# 预加载场景
var enemy_scene = preload("res://scenes/Enemy.tscn")

# 实例化
var enemy = enemy_scene.instantiate()
add_child(enemy)

材质 (Material)

# 2D 材质
var material = CanvasItemMaterial.new()
material.blend_mode = CanvasItemMaterial.BLEND_MODE_ADD

# 3D 材质
var standard_material = StandardMaterial3D.new()
standard_material.albedo_color = Color.RED
standard_material.roughness = 0.5

# 应用到节点
$Sprite2D.material = material
$MeshInstance3D.set_surface_override_material(0, standard_material)

资源路径

res:// (项目资源)

指向项目目录内的资源。

var texture = preload("res://images/sprite.png")

user:// (用户数据)

指向用户数据目录,用于保存游戏数据。

# 保存数据
var save_data = {"level": 5, "score": 1000}
var file = FileAccess.open("user://save.dat", FileAccess.WRITE)
file.store_var(save_data)
file.close()

# 加载数据
var file = FileAccess.open("user://save.dat", FileAccess.READ)
var data = file.get_var()
file.close()

res:// vs user://

路径 用途 写入 随游戏发布
res:// 游戏资源 只读
user:// 用户数据 可读写

资源加载

Preload (编译时加载)

# 在类顶部预加载
var player_scene = preload("res://scenes/Player.tscn")
var jump_sound = preload("res://sounds/jump.wav")

Load (运行时加载)

# 运行时动态加载
var scene = load("res://scenes/level_" + str(level_number) + ".tscn")

# 检查资源是否存在
var path = "res://textures/" + texture_name + ".png"
if ResourceLoader.exists(path):
    var texture = load(path)

异步加载

extends Control

var loader: ResourceLoader

func load_scene_async(path: String) -> void:
    loader = ResourceLoader.load_interactive(path)
    set_process(true)

func _process(delta: float) -> void:
    if loader:
        var status = loader.poll()
        var progress = loader.get_stage() / float(loader.get_stage_count())

        $ProgressBar.value = progress * 100

        if status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
            pass
        elif status == ResourceLoader.THREAD_LOAD_LOADED:
            var scene = loader.get_resource()
            change_scene_to_packed(scene)
            set_process(false)
        elif status == ResourceLoader.THREAD_LOAD_FAILED:
            print("加载失败")
            set_process(false)

资源释放

# 引用计数:当没有节点使用资源时自动释放

# 手动释放(很少需要)
resource.free()

# 排队释放(等待帧结束)
resource.queue_free()

资源导出设置

项目设置 -> Export

# 设置导出资源
# 在 .tscn 或 .gd 文件中使用 @export

@export var texture: Texture2D
@export var audio_stream: AudioStream
@export var scene: PackedScene

# 这些会在编辑器中显示,可以在导出时配置

资源压缩

纹理压缩

项目设置 -> Import Defaults -> Texture
- VRAM Compression: 启用(减少内存占用)
- HDR: Disable HDR(2D 游戏)
- Compression: DXT/ETC2(根据平台)

音频压缩

项目设置 -> Import Defaults -> Audio
- Format: Ogg Vorbis
- Compression: High

资源依赖

# 获取资源的依赖项
var resource = load("res://scenes/Player.tscn")
var dependencies = resource.get_dependencies()

# 导出资源及其依赖
export_scene("res://scenes/Player.tscn", "exported/player.scn")

资源热重载

# 编辑器中按 F5 或 Ctrl+Shift+R

# 代码中手动重载
ResourceLoader.reload_interactive("res://scenes/Player.tscn")

国际化资源

# 创建翻译文件
# .po 文件放置在 res://translations/

# 加载翻译
TranslationServer.add_translation(preload("res://translations/zh_CN.po"))
TranslationServer.set_locale("zh_CN")

# 获取翻译文本
tr("Hello")  # 返回翻译后的文本

资源最佳实践

  1. 使用 preload:对于经常使用的资源
  2. 使用 load:对于条件加载或运行时确定的资源
  3. 复用资源:尽量使用场景实例化而非复制
  4. 合理分类:按类型组织资源目录结构
  5. 导出设置:正确设置资源导出选项

资源目录结构示例

res://
├── assets/
│   ├── textures/
│   │   ├── characters/
│   │   ├── ui/
│   │   └── environment/
│   ├── models/
│   │   ├── characters/
│   │   └── props/
│   ├── audio/
│   │   ├── music/
│   │   └── sfx/
│   └── fonts/
├── scenes/
│   ├── player/
│   ├── enemies/
│   └── ui/
├── scripts/
│   ├── player/
│   └── systems/
├── resources/
│   ├── materials/
│   └── data/
└── translations/