技术笔记

Cocos Creator 中的资源组织与加载

基于 Cocos Creator 3.8 文档,区分场景引用、resources 与 Asset Bundle,整理资源划分和加载时需要关注的边界。

由绿色地块、路径和资源模块组成的游戏开发概念插画

游戏资源既有目录上的组织方式,也有运行时的加载关系。一个图片文件放在哪个文件夹,并不能单独说明它什么时候进入内存。整理资源时,应同时考虑场景引用、动态加载入口,以及资源由谁持有。

本文基于 Cocos Creator 3.8 官方文档梳理通用方法。示例目录与代码用于说明概念,不是本站实际游戏工程,也不包含性能测试结论。

先看资源如何被使用

场景中的直接引用

对于首个场景中始终需要的背景、按钮和预制体,可以优先使用编辑器中清楚的资源引用。维护时查看场景和预制体的依赖,比仅按图片、音频、材质分文件夹,更容易理解资源的用途。

普通文件夹是管理手段。是否进入构建、被哪个包依赖,还需要结合构建选项和引用关系核对。

按路径动态加载

当资源需要运行时按名称选择时,可以考虑 resources 或自定义 Asset Bundle。不要仅为“以后也许会用到”,把所有文件都放进 resources。先明确加载入口,可以减少无法判断用途的资源。

用 Asset Bundle 划分加载边界

Asset Bundle 适合按关卡、功能模块等组织可独立加载的内容。下面是一种讨论目录边界的示例:

assets/
├── scenes/          # 启动与常用场景
├── shared/          # 共享资源
└── level-one/       # 可配置为一个 Asset Bundle
    ├── prefabs/
    └── textures/

shared 这个目录名称没有特殊引擎语义。共享依赖最终如何分配,要检查 Bundle 配置和构建结果,不能仅凭目录名认定资源不会重复。

区分加载包与加载资源

assetManager.loadBundle() 完成后,得到的是包的访问入口;这不等于已经把包内每个资源都加载完。之后通过返回的 Bundle 加载需要的内容。以下示例省略了具体界面的生命周期处理:

import { assetManager, Prefab } from 'cc';

assetManager.loadBundle('level-one', (bundleError, bundle) => {
  if (bundleError) {
    console.error(bundleError);
    return;
  }

  bundle.load('prefabs/panel', Prefab, (assetError, prefab) => {
    if (assetError) {
      console.error(assetError);
      return;
    }
    // prefab 已加载;由调用方决定如何使用及何时释放。
  });
});

这里的资源路径相对于 Bundle 根目录,不带文件扩展名。真实组件还需要处理重复请求、加载失败,以及回调返回时界面已经关闭等情况。

把释放责任一起设计

资源加载成功只是流程的一半。离开关卡后,应确认哪些资源仍被节点或其他模块使用,再决定释放范围。随意调用批量释放方法,可能影响共享资源。

调试时可以沿着“谁请求、谁持有、何时结束使用”检查。加载慢则继续区分下载、反序列化与实例化等环节;没有采集数据前,不直接把问题归因于图片大小或 Bundle 数量。

参考资料