用途
本技能是 Godot 引擎中面向数据设计(data-oriented design)的专家蓝图,聚焦于使用 Resource 与 RefCounted 类来构建可复用的数据结构,例如物品数据库、角色属性模板、技能定义、对话表和敌人配置等。目标是让资源充当「可保存、可在 Inspector 中编辑的数据容器」,而把逻辑放到 Node 或专用的 RefCounted 类中。
主要能力
- 提供 Resource / RefCounted / Node 三者的选择决策树:Resource 用于共享定义、可保存数据、@export 编辑(.tres/.res,Inspector 可用);RefCounted 用于临时运行时计算、非持久化辅助对象(不落盘、Inspector 支持弱);Node 用于场景中带 process/信号、挂在树上的实体(场景文件)。
- 按场景提供必需脚本:
- 基于共享 .tres 的每实例可变属性(HP)→ resource_local_to_scene.gd
- 嵌套的 Item → Weapon → StatusEffect 树 / 保存整图 → nested_resource_serialization.gd
- 多实体共享一份配置(flyweight)→ resource_flyweight_caching.gd / flyweight_enemy_config.gd
- 自定义 @export 数据容器 → custom_data_resource.gd
- 带信号的反应式属性 → character_stats_resource.gd
- 基于 Resource 数组的库存 → resource_based_inventory.gd
- 将 Resource 树保存到磁盘 → resource_save_system.gd(需检查 Error)
- 运行前 preload / O(1) 缓存 → resource_preloading_strategy.gd
- 运行时 Resource.new() 掉落生成 → dynamic_resource_generation.gd
- 校验 / 池化 / 工厂 → resource_validator.gd / resource_pool.gd / data_factory_resource.gd
使用方式
技能以规则清单和模式脚本的形式给出。核心约束包括一条「NEVER 清单」:
- 绝不直接修改资源实例——若不调用 .duplicate(),修改 HP 之类的值会改到共享 .tres,影响所有引用者。
- 绝不在 Resource 中使用无类型数组——@export var items: Array 允许逻辑错误,应始终使用 Array[ResourceClass] 保证类型安全。
- 绝不在 Resource 中存放 Node 引用——只存在于特定 SceneTree 的对象无法序列化,应存 NodePath 或 UID。
- 绝不在 Resource 的 getter/setter 中做重计算——Resource 应是数据容器,逻辑应下沉到 Node 或专用 RefCounted 类。
- 绝不跳过 ResourceSaver.save() 的错误检查——保存可能因权限、磁盘空间或路径问题失败,必须检查返回码。
- 绝不用 Resource 承载高频运行时数据——若某值每秒变化 60 次(如 velocity),普通变量比 Resource 属性更快。
- 绝不允许 Resource 循环引用——A.tres 引用 B.tres 且 B.tres 引用 A.tres 时,引擎可能在加载时崩溃。
- 绝不忘记 _init 默认值——通过 new() 或在 Inspector 创建的 Resource 需要构造函数中的默认值才可编辑。
- 若实体需要各自独立状态,绝不共享同一个 Resource——组件应使用 resource_local_to_scene = true 或 duplicate()。
- 绝不用 .tres 承载超大数据集——若有 10,000 个物品,JSON 或自定义二进制格式可能比逐个 Resource 文件更高效。
此外技能给出了若干关键经验提示:
- 运行时 HP/mana 若直接写在共享 .tres 上且未 duplicate(true) 或设置 resource_local_to_scene,会改写磁盘上的资产,即「打到一个等于打到全部」的 bug。
- .res 与 .tres 的取舍:生产环境用二进制 .res,需要设计差分时用 .tres;嵌套树随父级一起通过 ResourceSaver 保存。
- 缓存:外部编辑后使用 ResourceLoader.CACHE_MODE_REPLACE 绕过陈旧缓存。
- local-to-scene / duplicate 对每实例组件是强制的。
- 万行以上数据:逐个 .tres 文件不如 JSON/二进制,可参考官方文档的二进制序列化。
适用场景
- 物品定义、属性模板、技能、对话表、敌人配置等共享定义型数据。
- 需要嵌套结构并整体保存的资源图(如武器带状态效果)。
- 多实体共享一份配置的 flyweight 缓存场景。
- 需要在 Inspector 中编辑并持久化的自定义数据容器。
- 需要信号驱动的反应式属性、基于 Resource 数组的库存与存档流程。
- RefCounted 适用于伤害计算的临时对象、短生命周期状态机、无需保存的工具类。
限制与注意事项
- 高频变化的数据(如每秒 60 次)不应使用 Resource 属性。
- Resource 不能存放仅存在于特定 SceneTree 的 Node 引用,需改用 NodePath 或 UID。
- 超大数据集(如 10,000 条以上)建议改用 JSON 或自定义二进制格式。
- 禁止循环资源引用,否则可能加载崩溃。
- 保存操作必须检查 ResourceSaver.save() 返回的 Error。
- 官方文档链接建议按需查阅:Resources、Data preferences、Resource、ResourceLoader、ResourceSaver、RefCounted、Saving games、Background loading、GDScript exports、Binary serialization API、Scene organization。
- 相关技能中,前置为 godot-project-foundations、godot-gdscript-mastery;互补为 godot-signal-architecture、godot-save-load-systems、godot-scene-management、godot-ability-system、godot-dialogue-system、godot-performance-optimization;下游消费者为 godot-inventory-system、godot-procedural-generation、godot-monte-carlo-balancer;总入口为 godot-master。
具体脚本实现细节、完整模式 1–7 的逐步讲解以及各官方 API 的用法示例,资料中未提供完整内容,需按需查阅对应资源文件与官方文档。