# 资源加载
纹理、材质、模型等游戏资源,在游戏项目中,它们是一系列静态文件;在游戏运行时,它们被实例化为一系列资源实例,被 UISprite、MeshRender 等 Component 依赖,参与渲染。
资源系统做了两件事:
- 在游戏项目构建时,打包资源文件。
- 在游戏运行时,加载资源文件,并创建资源实例。
先来了解资源是如何加载的。首先需要在project窗口内将想要加载的资源通过inspector下的import setting配置为入口资源。开发者不需要在代码中处理依赖关系,更无须处理资源文件的读取,只需调用 Loader.prototype.load(),就可以获取加载并实例化后的资源。Loader 是用来加载资源的加载器 Class。资源系统的核心 API、也是 Loader 的核心 API,只有 2 个:
- Loader.prototype.load() 用来异步加载资源。
- Loader.prototype.getAsset() 用来同步获取已下载的资源。
Loader.prototype.load() 会返回一个 LoadTask,可以监听加载任务的结果,也可以中断它。Loader.load()的第一个参数为资源相对于游戏根目录/assets/
的路径。
假设 SpriteFrame 的绝对路径为
游戏根目录/assets/Assets/image.spriteframe
,那么它相对于游戏根目录/assets/
的路径为Assets/image.spriteframe
。
// 加载一个prefab
const task = engine.loader.load("resource/Aircraft.prefab");
task.promise.then((prefab) => {
console.log(prefab)
}).catch((error) => {
console.error(error);
})
// 中断任务,task.promise 的 catch 会执行
task.abort();
资源加载成功后,如果想要以同步调用的方式获取资源实例,可以调用 Loader.prototype.getAsset()。
// 如果尚未加载、加载未完成,会抛出错误
try {
const spriteFrame = engine.loader.getAsset("resource/Aircraft.prefab");
}
catch (e) {
console.error(e)
}
# LoadTask
engine.loader.load返回的是一个LoadTask实例,LoadTask 是返回给业务层的下载任务类,是一个“一次性”的类。从实例化到所依赖的 资源包 全部完成加载(成功或失败),状态不再改变。
比如可以使用LoadTask.progress来获取进度,通过abort()来终止任务。
# 加载器的额外选项
在使用Loader.load()加载资源时,可以在第二个参数处,传入额外的下载选项。
常用选项 | 类型 | 描述 |
---|---|---|
httpRetryCount | number | 下载失败后的重试次数。 |
httpPriority | number | 下载优先级。 |
preload | boolean | 预加载,下载完毕后不读取文件。 |
raw | boolean | 加载原始文件内容。 |
engine.loader.load("resource/Aircraft.prefab", {
httpRetryCount: 2,
priority: 10
}).promise.then((spriteFrame) => {
console.log(spriteFrame)
})
# 全局重试次数
如果不想每次load()都传递额外参数,可以直接在全局配置里设定全局重试次数。
在工具中打开Project Setting标签 >> 游戏配置 >> globalSetting >> globalHTTPRetry
# 资源下载优化
为了让用户能更快的进入游戏,开发者也可以通过以下几种方式优化自己的游戏逻辑。
提前下载:对于首次进入游戏的用户,一般会先进入loading界面,那么可以在loading界面就可以提前开始下载游戏资源,下载会在多线程worker中运行,不会对主进程造成过多影响。
按需下载:对于用户不即时需要的游戏资源没有必要立刻下载好,可以在用到的时候再下载,这里需要开发者针对自己的场景做优化。
烘培流式加载场景:小游戏针对大型场景实现的按距离逐步下载场景资源的能力,实现超大地图秒开。可以查看文档了解详情。