跳转到内容

资源加载

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 自动完成以下步骤:

  1. 获取 atlas 文件并写入虚拟文件系统
  2. 解析 atlas 中的纹理文件名并逐一加载
  3. 获取骨骼文件(.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

选项类型说明
baseUrlstring覆盖此请求的基础 URL
noCacheboolean跳过缓存,始终从网络获取

批量加载

使用 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

字段类型说明
texturesstring[]纹理图片路径
materialsstring[]材质文件路径(.esmaterial)
spineSpineDescriptor[]Spine 骨骼/图集对
jsonstring[]JSON 文件路径
textstring[]文本文件路径
binarystring[]二进制文件路径

AssetBundle

返回的 AssetBundle 包含以路径为键的 Map:

字段类型
texturesMap<string, TextureInfo>
materialsMap<string, LoadedMaterial>
spineMap<string, SpineLoadResult>
jsonMap<string, unknown>
textMap<string, string>
binaryMap<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);

下一步