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


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


一、资源的加载


1、动态加载资源


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

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

(1)、加载预制体

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 可以加载相同路径下的多个资源:

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

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

(7)、加载远程资源

// 远程 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;

猜你喜欢

转载自blog.csdn.net/lizhong2008/article/details/132858197