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;

相关推荐
刘婉晴11 分钟前
【信息安全工程师备考笔记】第三章 密码学基本理论
笔记·安全·密码学
晓数2 小时前
【硬核干货】JetBrains AI Assistant 干货笔记
人工智能·笔记·jetbrains·ai assistant
我的golang之路果然有问题3 小时前
速成GO访问sql,个人笔记
经验分享·笔记·后端·sql·golang·go·database
lwewan3 小时前
26考研——存储系统(3)
c语言·笔记·考研
胜天半子_王二_王半仙3 小时前
godot源码编译
游戏引擎·godot
搞机小能手3 小时前
六个能够白嫖学习资料的网站
笔记·学习·分类
nongcunqq4 小时前
爬虫练习 js 逆向
笔记·爬虫
Tandy12356_4 小时前
Godot开发2D冒险游戏——第二节:主角光环整起来!
游戏引擎·godot
汐汐咯4 小时前
终端运行java出现???
笔记
无敌小茶6 小时前
Linux学习笔记之环境变量
linux·笔记