CocosCreator3.8研究笔记(十四)CocosCreator 资源管理Asset Manager

在游戏的开发过程中,需要使用到大量的图片、音频等资源来,从而带来管理上的困难。 Asset Manager 资源管理模块具备加载资源、查找资源、销毁资源、缓存资源、Asset Bundle 等功能,帮助开发者管理其资源的使用。

一、资源的加载

1、动态加载资源

Asset Manager 提供了以下两种的方式:

  • 将资源放在 resources 目录下,配合 resources.load 等 API 来实现动态加载。
  • 将资源制作为 Asset Bundle,再通过 Asset Bundle 的 load 系列 API 进行资源的加载。

(1)、加载预制体

typescript 复制代码
resources.load("test/prefab", Prefab, (err, prefab) => {
    const newNode = instantiate(prefab);
    this.node.addChild(newNode);
});

(2)、 加载 AnimationClip

resources.load("test/anim", AnimationClip, (err, clip) => {s
    this.node.getComponent(Animation).addClip(clip, "anim");
});

(3)、 加载 SpriteFrame

加载SpriteFrame image是ImageAsset spriteFrame

是image/spriteFrame texture是image/texture

resources.load("test/image/spriteFrame", SpriteFrame, (err, spriteFrame) => {
    this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});

(4)、 加载 Texture2D

resources.load("test/image/texture", Texture2D, (err: any, texture: Texture2D) => {
    const spriteFrame = new SpriteFrame();
    spriteFrame.texture = texture;
    this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});

(5)、 加载图集中的 SpriteFrame

resources.load("test/SpriteAtlas", SpriteAtlas, (err, atlas) => {
    const frame = atlas.getSpriteFrame('name');
    sprite.spriteFrame = frame;
});

(6)、 资源批量加载

resources.loadDir 可以加载相同路径下的多个资源:

typescript 复制代码
//加载 test目录下所有资源
resources.loadDir("test", function (err, assets) {
    // ...
});

//加载 test目录下所有 SpriteFrame,并且获取它们的路径
resources.loadDir("test", SpriteFrame, function (err, assets) {
    // ...
});

(7)、加载远程资源

typescript 复制代码
// 远程 url 带图片后缀名
let remoteUrl = "http://test.com/image.png";
assetManager.loadRemote<ImageAsset>(remoteUrl, function (err, imageAsset) {
    const spriteFrame = new SpriteFrame();
    const texture = new Texture2D();
    texture.image = imageAsset;
    spriteFrame.texture = texture;
    // ...
});


// 远程 url 不带图片后缀名,此时必须指定远程图片文件的类型
remoteUrl = "http://test.com/emoji?id=123456";
assetManager.loadRemote<ImageAsset>(remoteUrl, {ext: '.png'}, function (err, imageAsset) {
    const spriteFrame = new SpriteFrame();
    const texture = new Texture2D();
    texture.image = imageAsset;
    spriteFrame.texture = texture;
    // ...
});

// 远程音频
remoteUrl = "http://test.com/sound.mp3";
assetManager.loadRemote(remoteUrl, function (err, audioClip) {
    // play audio 
});

// 远程文本
remoteUrl = "http://unknown.org/skill.txt";
assetManager.loadRemote(remoteUrl, function (err, textAsset) {
    // use string to do something
});

(8)、加载设备资源

用绝对路径加载设备存储内的资源

const absolutePath = "/dara/data/some/path/to/image.png";
assetManager.loadRemote<ImageAsset>(absolutePath, function (err, imageAsset) {
    const spriteFrame = new SpriteFrame();
    const texture = new Texture2D();
    texture.image = imageAsset;
    spriteFrame.texture = texture;
});

(9)、加载Asset Bundle

关于 Asset Bundle 的介绍,资源加载及使用,请查看下一篇文章。

(10)、资源预加载

为了减少下载的延迟,assetManager 和 Asset Bundle 提供了对应的预加载接口。

预加载只会下载必要的资源,不会进行反序列化和初始化工作,性能消耗小,适合在游戏过程中使用。

Asset Manager 中的大部分加载接口包括 loadloadDirloadScene 都有其对应的预加载版本,如下表:

类型 支持 加载 释放 预加载 获取 查询资源信息
单个资源 Asset Bundle load release preload get getInfoWithPath
文件夹 Asset Bundle loadDir releaseAsset preloadDir N/A getDirWithPath
场景 Asset Bundle loadScene N/A preloadScene N/A getSceneInfo
单个资源 resources load release preload get getInfoWithPath
文件夹 resources loadDir releaseAsset preloadDir N/A getDirWithPath
远程 Asset Manager loadRemote releaseAsset N/A N/A N/A

资源加载接口与预加载接口所用参数完全一样,区别在于:

  • 预加载只会下载资源,不会对资源进行解析和初始化操作
  • 预加载在加载过程中会受到更多限制,例如最大下载并发数会更小
  • 预加载的下载优先级更低,当多个资源在等待下载时,预加载的资源会放在最后下载
  • 因为预加载没有做任何解析操作,所以当所有的预加载完成时,不会返回任何可用资源

由于预加载没有解析资源,所以需要在预加载完成后,再配合加载接口进行资源的解析和初始化。

例如:

resources.preload('images/background/spriteFrame', SpriteFrame);

// wait for while 
resources.load('images/background/spriteFrame', SpriteFrame, function (err, spriteFrame) {
    spriteFrame.addRef();
    self.getComponent(Sprite).spriteFrame = spriteFrame;
});

注意:加载不需要等到预加载完成后再调用,开发者可以在任何时候进行加载。

正常加载接口会直接复用预加载过程中已经下载好的内容,缩短加载时间。

二、资源的释放

Asset Manager对依赖资源根据引用数量进行释放。

例如:

resources.load('prefabs/test', Prefab, function (err, asset) {
    assetManager.releaseAsset(asset);
});

Creator 还提供了引用计数机制来控制资源的引用和释放:

  • 当需要持有资源时,调用 addRef 来增加引用,确保该资源不会被其他引用到的地方自动释放。

    resources.load('test/texture/image', Texture2D, function (err, texture) {
    texture.addRef();
    this.texture = texture;
    });

  • 当不再需要持有该资源时,调用 decRef 来减少引用,decRef 还将根据引用计数尝试自动释放。

    this.texture.decRef();
    this.texture = null;

相关推荐
霍格沃兹测试开发学社测试人社区18 分钟前
软件测试学习笔记丨Flask操作数据库-数据库和表的管理
软件测试·笔记·测试开发·学习·flask
幸运超级加倍~39 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
charon87781 小时前
UE ARPG | 虚幻引擎战斗系统
游戏引擎
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
Yawesh_best2 小时前
思源笔记轻松连接本地Ollama大语言模型,开启AI写作新体验!
笔记·语言模型·ai写作
小春熙子2 小时前
Unity图形学之Shader结构
unity·游戏引擎·技术美术
CXDNW3 小时前
【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
网络·笔记·http·面试·https·http2.0
使者大牙3 小时前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型
ssf-yasuo4 小时前
SPIRE: Semantic Prompt-Driven Image Restoration 论文阅读笔记
论文阅读·笔记·prompt
ajsbxi4 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet