• 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);
    });
    
    • 1
    • 2
    • 3
    • 4

    (2)、 加载 AnimationClip

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

    (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;
    });
    
    • 1
    • 2
    • 3

    (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;
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (5)、 加载图集中的 SpriteFrame

    resources.load("test/SpriteAtlas", SpriteAtlas, (err, atlas) => {
        const frame = atlas.getSpriteFrame('name');
        sprite.spriteFrame = frame;
    });
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (6)、 资源批量加载

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

    //加载 test目录下所有资源
    resources.loadDir("test", function (err, assets) {
        // ...
    });
    
    //加载 test目录下所有 SpriteFrame,并且获取它们的路径
    resources.loadDir("test", SpriteFrame, function (err, assets) {
        // ...
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (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
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    (8)、加载设备资源

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

    const absolutePath = "/dara/data/some/path/to/image.png";
    assetManager.loadRemote(absolutePath, function (err, imageAsset) {
        const spriteFrame = new SpriteFrame();
        const texture = new Texture2D();
        texture.image = imageAsset;
        spriteFrame.texture = texture;
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (9)、加载Asset Bundle

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


    (10)、资源预加载

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

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

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

    类型支持加载释放预加载获取查询资源信息
    单个资源Asset BundleloadreleasepreloadgetgetInfoWithPath
    文件夹Asset BundleloadDirreleaseAssetpreloadDirN/AgetDirWithPath
    场景Asset BundleloadSceneN/ApreloadSceneN/AgetSceneInfo
    单个资源resourcesloadreleasepreloadgetgetInfoWithPath
    文件夹resourcesloadDirreleaseAssetpreloadDirN/AgetDirWithPath
    远程Asset ManagerloadRemotereleaseAssetN/AN/AN/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;
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

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


    二、资源的释放


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

    例如:

    resources.load('prefabs/test', Prefab, function (err, asset) {
        assetManager.releaseAsset(asset);
    });
    
    
    • 1
    • 2
    • 3
    • 4

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


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

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

    • 当不再需要持有该资源时,调用 decRef 来减少引用,decRef 还将根据引用计数尝试自动释放。
    this.texture.decRef();
    this.texture = null;
    
    • 1
    • 2

  • 相关阅读:
    面经汇总-社招-6年
    如何使用python连接mysql数据库编写爬虫代码。
    AI大模型高速发展,Web3还远吗?
    elasticsearch 其他优化
    缓存技术(缓存穿透,缓存雪崩,缓存击穿)
    基于 vite2 + Vue3 写一个在线帮助文档工具
    [MySQL远程备份策略举例]
    Nature | 美国博导学术霸凌亚洲博士后黑幕
    大学生HTML CSS动漫主题网页制作——刀剑神域(6页) dreamweaver作业静态HTML网页设计
    Android studio连接MySQL并完成简单的登录注册功能
  • 原文地址:https://blog.csdn.net/lizhong2008/article/details/132858197