资源加载
ESEngine 提供 Assets 资源(AssetServer 实例)来加载纹理、Spine 动画、材质和通用文件。在任何系统中通过 Res(Assets) 访问。
访问 Assets
import { defineSystem, addStartupSystem, Res } from 'esengine';import { Assets } from 'esengine';
addStartupSystem(defineSystem( [Res(Assets)], async (assets) => { const tex = await assets.loadTexture('assets/player.png'); console.log(`加载完成 ${tex.width}x${tex.height},handle: ${tex.handle}`); }));纹理加载
loadTexture(path)
加载图片并返回 TextureInfo 对象。图片会自动垂直翻转以适配 OpenGL UV 坐标。
const tex = await assets.loadTexture('assets/player.png');sprite.texture = tex.handle;返回值: TextureInfo { handle: TextureHandle, width: number, height: number }
其他纹理方法
| 方法 | 说明 |
|---|---|
getTexture(path) | 返回已缓存的 TextureInfo,未加载则返回 undefined |
hasTexture(path) | 判断纹理是否已缓存 |
releaseTexture(path) | 从 GPU 内存和缓存中释放纹理 |
releaseAll() | 释放所有已缓存的资源 |
九宫格元数据
对于九宫格精灵,加载后设置边框元数据:
const tex = await assets.loadTexture('assets/panel.png');assets.setTextureMetadata(tex.handle, { left: 10, right: 10, top: 10, bottom: 10});Spine 加载
const result = await assets.loadSpine('assets/hero.json', 'assets/hero.atlas');if (!result.success) { console.error(result.error);}loadSpine 自动完成以下步骤:
- 获取 atlas 文件并写入虚拟文件系统
- 解析 atlas 中的纹理文件名并逐一加载
- 获取骨骼文件(
.json或.skel二进制)并写入虚拟文件系统
| 方法 | 说明 |
|---|---|
loadSpine(skeleton, atlas, baseUrl?) | 加载 Spine 骨骼和图集 |
isSpineLoaded(skeleton, atlas) | 检查 Spine 资源对是否已加载 |
位图字体加载
const fontHandle = await assets.loadBitmapFont('assets/my-font.fnt');支持 .fnt(BMFont 文本格式)和 .bmfont(JSON 元数据)文件。加载器会自动解析并加载引用的纹理图集。
| 方法 | 返回值 | 说明 |
|---|---|---|
loadBitmapFont(path) | Promise<number> | 加载位图字体文件及其纹理,返回字体句柄 |
getFont(path) | number | undefined | 获取已缓存的字体句柄,未加载则返回 undefined |
releaseFont(path) | void | 从内存中释放字体及其纹理 |
通用文件加载
| 方法 | 返回值 | 说明 |
|---|---|---|
loadJson<T>(path, options?) | Promise<T> | 加载并解析 JSON 文件 |
loadText(path, options?) | Promise<string> | 加载文本文件 |
loadBinary(path, options?) | Promise<ArrayBuffer> | 加载二进制文件 |
const config = await assets.loadJson<GameConfig>('assets/config.json');const csv = await assets.loadText('assets/levels.csv');const data = await assets.loadBinary('assets/tilemap.bin');FileLoadOptions
| 选项 | 类型 | 说明 |
|---|---|---|
baseUrl | string | 覆盖此请求的基础 URL |
noCache | boolean | 跳过缓存,始终从网络获取 |
批量加载
使用 loadAll 并行加载多种资源:
const bundle = await assets.loadAll({ textures: ['assets/bg.png', 'assets/player.png'], spine: [{ skeleton: 'assets/hero.json', atlas: 'assets/hero.atlas' }], json: ['assets/config.json'],});
// 从 bundle 中访问已加载的资源const bgTex = bundle.textures.get('assets/bg.png');const config = bundle.json.get('assets/config.json');AssetManifest
| 字段 | 类型 | 说明 |
|---|---|---|
textures | string[] | 纹理图片路径 |
materials | string[] | 材质文件路径(.esmaterial) |
spine | SpineDescriptor[] | Spine 骨骼/图集对 |
json | string[] | JSON 文件路径 |
text | string[] | 文本文件路径 |
binary | string[] | 二进制文件路径 |
AssetBundle
返回的 AssetBundle 包含以路径为键的 Map:
| 字段 | 类型 |
|---|---|
textures | Map<string, TextureInfo> |
materials | Map<string, LoadedMaterial> |
spine | Map<string, SpineLoadResult> |
json | Map<string, unknown> |
text | Map<string, string> |
binary | Map<string, ArrayBuffer> |
材质加载
const loaded = await assets.loadMaterial('assets/effects/glow.esmaterial');sprite.material = loaded.handle;详见材质与着色器了解完整的材质 API 和 .esmaterial 文件格式。
缓存机制
所有加载方法按路径缓存。同一路径加载两次会直接返回缓存结果,不会再次发起网络请求。使用 noCache 选项跳过缓存:
const fresh = await assets.loadJson('assets/config.json', { noCache: true });基础 URL
设置 assets.baseUrl 为所有相对路径添加前缀:
assets.baseUrl = 'https://cdn.example.com/game';const tex = await assets.loadTexture('sprites/player.png');// 请求 https://cdn.example.com/game/sprites/player.png绝对路径和完整 URL 不受 baseUrl 影响。
嵌入式资源
对于 Playable Ad 构建,编辑器的构建流程会自动将所有引用的资源以 data URI 形式嵌入输出包中。运行时 assets.loadTexture() / assets.loadJson() 等加载调用会直接从嵌入数据解析,无需网络请求,也无需修改任何代码。
Addressable 资产
Addressable 资产允许通过逻辑地址、标签或分组加载资源,而非直接使用文件路径。编辑器在构建过程中生成 AddressableManifest,将地址和标签映射到资产路径。
按地址加载
const texture = await assets.loadByAddress('player-idle');按标签加载
加载标记了某个标签的所有资产,返回 AssetBundle:
const bundle = await assets.loadByLabel('ui-sprites');for (const [path, tex] of bundle.textures) { console.log(`已加载 ${path}: ${tex.width}x${tex.height}`);}按分组加载
加载某个命名分组中的所有资产:
const bundle = await assets.loadGroup('level-1');设置清单
清单由编辑器在构建时生成。运行时在加载前设置:
import { Assets } from 'esengine';
const manifest = await assets.loadJson('assets/addressable-manifest.json');assets.setAddressableManifest(manifest);