godot-resources

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Godot Resources (4.x)

Godot Resources (4.x)

Model game data as reusable, Inspector-editable
Resource
objects instead of hard-coded values, and load/save them as
.tres
/
.res
. Targets Godot 4.3+.
将游戏数据建模为可复用、可在Inspector中编辑的
Resource
对象,而非硬编码值,并以
.tres
/
.res
格式加载/保存。适用于**Godot 4.3+**版本。

When to use

适用场景

  • Use when representing items, stats, enemy configs, dialogue lines, or level metadata as data; authoring
    .tres
    files in the Inspector; or loading/saving custom resources.
When not to use: nodes/scene structure →
godot-nodes-scenes
; saving the player's runtime progress (engine-agnostic save format/slots) →
save-systems
; the C# variant of this pattern →
godot-csharp
.
  • 适用于将物品、属性、敌人配置、对话内容或关卡元数据表示为数据的场景;在Inspector中编辑
    .tres
    文件;或加载/保存自定义资源时使用。
不适用场景:节点/场景结构 →
godot-nodes-scenes
;保存玩家的运行时进度(与引擎无关的保存格式/存档槽)→
save-systems
;此模式的C#变体 →
godot-csharp

Core workflow

核心工作流程

  1. Subclass
    Resource
    with
    class_name
    and
    @export
    fields. It now appears in the "New Resource" dialog and as an
    @export
    type, editable in the Inspector.
  2. Create instances as
    .tres
    files in the FileSystem dock (text, diff-friendly) or
    .res
    (binary, smaller/faster). Edit their fields in the Inspector — no code needed.
  3. Reference resources from nodes via
    @export var data: ItemResource
    , or arrays
    @export var loot: Array[ItemResource]
    .
  4. Load at runtime with
    preload
    (constant path) or
    load
    /
    ResourceLoader.load
    (variable path). Use threaded loading for large assets.
  5. Duplicate before mutating a shared resource at runtime, or every node using it changes too (resources are shared references).
  6. Save generated/edited resources with
    ResourceSaver.save
    .
  1. 继承
    Resource
    :使用
    class_name
    @export
    字段定义子类。该类现在会出现在“新建资源”对话框中,且作为
    @export
    类型可在Inspector中编辑。
  2. 创建
    .tres
    实例
    :在文件系统面板中创建
    .tres
    文件(文本格式,支持差异对比)或
    .res
    文件(二进制格式,体积更小、加载更快)。无需编写代码,直接在Inspector中编辑其字段。
  3. 从节点引用资源:通过
    @export var data: ItemResource
    或数组
    @export var loot: Array[ItemResource]
    引用资源。
  4. 运行时加载:使用
    preload
    (固定路径)或
    load
    /
    ResourceLoader.load
    (可变路径)加载资源。大型资源可使用线程加载。
  5. 修改前复制资源:在运行时修改共享资源前需调用
    duplicate
    ,否则所有使用该资源的节点都会受到影响(资源为共享引用)。
  6. 保存生成/编辑的资源:使用
    ResourceSaver.save
    保存资源。

Patterns

模式示例

1. A custom data resource

1. 自定义数据资源

gdscript
undefined
gdscript
undefined

item.gd

item.gd

extends Resource class_name ItemResource
@export var id: StringName = &"" @export var display_name: String = "Item" @export_multiline var description: String = "" @export var icon: Texture2D @export var max_stack: int = 99 @export var value: int = 0

Create `sword.tres` from this class in the FileSystem dock and fill it in the Inspector.
extends Resource class_name ItemResource
@export var id: StringName = &"" @export var display_name: String = "Item" @export_multiline var description: String = "" @export var icon: Texture2D @export var max_stack: int = 99 @export var value: int = 0

在此类基础上,在文件系统面板中创建`sword.tres`文件,并在Inspector中填写内容。

2. Consume resources from a node

2. 从节点中使用资源

gdscript
extends Node
@export var starting_items: Array[ItemResource] = []   # drag .tres files in the Inspector

func _ready() -> void:
    for item in starting_items:
        print("Have: %s (x%d max)" % [item.display_name, item.max_stack])
gdscript
extends Node
@export var starting_items: Array[ItemResource] = []   # 在Inspector中拖拽.tres文件

func _ready() -> void:
    for item in starting_items:
        print("拥有:%s(最大堆叠数:%d)" % [item.display_name, item.max_stack])

3. Duplicate before mutating shared data

3. 修改共享数据前复制资源

gdscript
func give_unique_copy(template: ItemResource) -> ItemResource:
    # true = deep copy sub-resources too; false = shallow (shares sub-resources).
    var copy: ItemResource = template.duplicate(true)
    copy.value += 5                # mutating the copy won't touch the template .tres
    return copy
gdscript
func give_unique_copy(template: ItemResource) -> ItemResource:
    # true = 深度复制子资源;false = 浅复制(共享子资源)。
    var copy: ItemResource = template.duplicate(true)
    copy.value += 5                # 修改副本不会影响模板.tres文件
    return copy

4. Save and load a resource at runtime

4. 运行时保存和加载资源

gdscript
func save_config(cfg: Resource) -> void:
    ResourceSaver.save(cfg, "user://config.tres")   # user:// = writable app data dir

func load_config() -> Resource:
    if ResourceLoader.exists("user://config.tres"):
        return ResourceLoader.load("user://config.tres")
    return null
gdscript
func save_config(cfg: Resource) -> void:
    ResourceSaver.save(cfg, "user://config.tres")   # user:// = 可写入的应用数据目录

func load_config() -> Resource:
    if ResourceLoader.exists("user://config.tres"):
        return ResourceLoader.load("user://config.tres")
    return null

Pitfalls

注意事项

  • Resources are shared by reference. A single
    .tres
    assigned to many nodes is the same object — mutating it changes all of them (and re-saving the file). Call
    duplicate(true)
    for per-instance state.
  • class_name
    required to instance from the editor.
    Without it the class won't appear in the "New Resource" dialog or as an
    @export
    type.
  • res://
    is read-only in exported games.
    Write runtime data to
    user://
    , never
    res://
    .
    ResourceSaver.save
    to
    res://
    only works in the editor.
  • Storing nodes in a Resource doesn't serialize them. Resources hold data, not live scene nodes. Reference scenes via
    PackedScene
    , not node instances.
  • Cyclic resource references (A holds B holds A) can fail to save/load cleanly — keep data graphs acyclic or use IDs/lookups.
  • preload
    vs
    load
    .
    preload
    needs a constant path and loads with the script;
    load
    accepts a variable path at runtime. Use
    ResourceLoader.exists()
    before
    load
    to avoid errors on missing files.
  • Don't put secrets in
    .tres
    — they ship in plain text inside the export.
  • 资源为共享引用:单个
    .tres
    文件被多个节点引用时,它们指向的是同一个对象——修改该对象会影响所有引用它的节点(并会重新保存文件)。如需每个实例独立状态,请调用
    duplicate(true)
  • 必须添加
    class_name
    才能在编辑器中实例化
    :没有
    class_name
    的话,该类不会出现在“新建资源”对话框中,也无法作为
    @export
    类型使用。
  • 导出游戏后
    res://
    为只读
    :运行时数据需写入
    user://
    ,绝不能写入
    res://
    。仅在编辑器中才能使用
    ResourceSaver.save
    将资源保存到
    res://
  • 资源中存储节点无法序列化:资源用于存储数据,而非实时场景节点。需通过
    PackedScene
    引用场景,而非节点实例。
  • 循环资源引用(A包含B,B包含A)可能导致保存/加载失败——请保持数据图无环,或使用ID/查找方式。
  • preload
    load
    的区别
    preload
    需要固定路径,会随脚本一起加载;
    load
    支持运行时可变路径。加载前使用
    ResourceLoader.exists()
    可避免文件缺失导致的错误。
  • 不要在
    .tres
    中存储敏感信息
    ——它们会以明文形式随导出包发布。

References

参考资料

  • For threaded/background loading (
    load_threaded_request
    ),
    @tool
    resources with custom setup, custom
    ResourceFormatLoader
    /
    Saver
    , resource-local-to-scene, and resource UIDs, read
    references/resource-patterns.md
    .
  • 如需了解线程/后台加载(
    load_threaded_request
    )、带自定义设置的
    @tool
    资源、自定义
    ResourceFormatLoader
    /
    Saver
    、场景本地资源及资源UID,请阅读
    references/resource-patterns.md

Related skills

相关技能

  • godot-gdscript
    @export
    annotations used to define resource fields.
  • godot-nodes-scenes
    — instancing scenes vs. sharing resource data.
  • save-systems
    — persisting runtime progress (separate from static data).
  • unity-scriptableobjects
    — the equivalent data-asset pattern in Unity.
  • godot-gdscript
    —— 用于定义资源字段的
    @export
    注解。
  • godot-nodes-scenes
    —— 实例化场景与共享资源数据的区别。
  • save-systems
    —— 持久化运行时进度(与静态数据分离)。
  • unity-scriptableobjects
    —— Unity中对应的资源数据模式。