赞
踩
版本: 3.4.0
语言: TypeScript
环境: Mac
在cocosCreator中,我们所有的资源都是放在 assets目录下, 只有放在该目录下的资源,编译器才能使用。
该目录下的所有资源均继承于 Assets
,我们简单看下继承结构:
更多参考: cocosCreator 之 通过cc.d.ts了解Assets资源
在 assets 目录下的资源,主要分为两大类:
两者主要的区别在于: 资源是否放在 assets/resources 目录中。
静态引用的资源,编译器会对资源进行序列化操作。引擎会将这类资源记录在序列化数据中,并通过引用计数进行内存管理和释放。
动态加载的资源主要通过resources.load
在代码中动态加载设置到指定的场景组件中。引擎这对于这类资源时不会记录在序列化数据中,也就无法统计引用关系进行内存管理。
注:序列化可理解为将资源对象转为一种可存储或传输的格式。
两者相比较:
针对于动态加载资源,细分的话又会有两种:
resources.load
动态加载资源Bunddle.load
动态加载资源在这里,我们看下编译器对resources目录的说明相关:
从图示中,我们可以了解到:
resources.load
方法的都必须放置在 resources目录中Bundle 可以理解为"包", 是cocosCreator官方提供的资源模块化工具,它的特点是:
本篇文章将主要讲述下关于resources
的使用相关,主要内容:
至于关于Bundle相关将在下篇博客进行分享:
理解可能有误,请提出您宝贵的建议,感激不尽。
resources是官方的内置Bundle,其定义实现如下:
// resources 是一个 bundle,用于管理所有在 assets/resources 下的资源
export const resources: AssetManager.Bundle;
resources 就是 Bundle,但 Bundle会有很多个,他们的使用方法是一样的。
主要接口如下:
名字 | 描述 |
---|---|
name | bundle的名称 |
base | bundle的根路径 |
getInfoWithPath(path, type) | 通过路径获取指定资源的配置信息 |
getDirWithPath(path, type, out) | 获取某个指定文件夹下的所有资源信息 |
getAssetInfo(uuid) | 通过uuid获取资源信息 |
getSceneInfo(name) | 通过场景名获取场景信息 |
load(path, type, onPrgress, onComplete) | 通过相对路径加载资源 |
loadDir(dir, type, onProgree, onComplete) | 加载目标文件夹中的所有资源 |
loadScene(name, optins, onProgress, onComplete) | 通过场景名称加载分包中的场景 |
preload(paths,type, onProgress, onComplete) | 通过相对路径预加载分包中的资源 |
preloadDir(dir, type, onProgress, onComplete) | 预加载目标文件夹中的所有资源 |
preloadScene(name, optins, onProgress, onComplete) | 通过场景名称预加载分包中的场景 |
releaseUnusedAssets() | 释放此包中的所有没有用到的资源 |
releaseAll() | 释放此包中的所有资源 |
简要理解就是:
loadXXX
实现加载单一资源、目录、场景等preloadXXX
实现预加载资源,目录,场景等releaseXXX
进行释放资源简单的使用:
// 加载背包的prefab页面
resources.load("prefab/bagLayer", Prefab, (err, prefab) => {
if(err) {
return console.err("Load Prefab fail");
}
const node = instantiate(prefab);
bagNode.parent = this.node;
});
// 加载某音效
let path = "prefab/sound/" + name;
resources.load(path, AudioClip, (err, clip) =>{
if(err) {
return console.err("load audioClip failed:" + err);
}
this._audioSource.playOneShot(clip, 1);
});
// 替换图片资源
const url = "textures/common/icon_gold/spriteFrame"
resources.load(url, SpriteFrame, (err, spriteframe)=> {
if (err) {
return console.err("load SpriteFrame failed:" + err);;
}
let sprite = this.node.getComponent(Sprite);
sprite.spriteFrame = spriteframe;
});
resources.load
支持着多种类型的添加,但要注意:
spriteFrame
或texture
相关resources目录下的资源有个特点:需要的时候就进行动态加载。 但资源如果过大,可能就会 卡顿。
不仅仅对于resources,对于其他的Bundle 来说,加载卡顿是必然的问题。
因此官方的Bundle
提供了preload
、preloadDir
、preloadScene
等接口,他们的特点是:
const url = 'images/background/spriteFrame';
// 预加载某个资源
resources.preload(url, SpriteFrame);
// 加载某个资源不需要等预加载结束
resources.load(url, SpriteFrame, function (err, spriteFrame) {
spriteFrame.addRef();
self.getComponent(Sprite).spriteFrame = spriteFrame;
});
预加载的资源,cocosCreator会将资源放到一个缓存表中,当使用某些资源的时候,会首先检测缓存表中是否存在,如果存在,则直接使用缓存表中的资源;如果不存在,则会开始查找和加载资源。
注:bundle的加载或预加载接口都是异步的,以避免堵塞主线程;
在项目开发中,预加载的主要应用地方是:loading页面,需要显示加载进度甚至要求显示加载的文件相关
因条件限制,本文使用 resources目录进行预加载
注:一般不会专门的对resources目录进行预加载,在熟悉Bundle以后,远程下载Bundle并进行预加载可作为参考
我们需要准备:一个Layer页面,主要节点: 进度条和描述文本
主要代码实现:
import { _decorator, assetManager, clamp01, Component, director, Label, ProgressBar, resources } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('UI_LoadingLayer')
export class UI_LoadingLayer extends Component {
@property(ProgressBar) loadBar: ProgressBar = null; // 进度条
@property(Label) desc: Label = null; // 描述文本
protected onLoad(): void {
// 获取已加载的分包
let resourceBundle = assetManager.bundles.get("resources");
resourceBundle = assetManager.getBundle("resources");
resourceBundle = assetManager.resources;
// 获取某个指定文件夹下的所有资源信息
const resourcePaths = resourceBundle.getDirWithPath("./");
console.log("resourcePaths", resourcePaths);
const maxLen = resourcePaths.length;
// 设置进度相关
this.desc.string = ""
this.loadBar.progress = 0;
let loadCount = 0;
for(let i = 0; i < maxLen; ++i) {
const path = resourcePaths[i].path;
resources.preload(path,
(completedCount: number, totalCount: number, item) => {
//console.log("progress:", completedCount, totalCount);
},
(err: Error | null, data: any) => {
if (err) {
return console.error("preload failed: " + err.message);
}
// 加载进度改变
loadCount++;
this.desc.string = `加载${path}`
this.loadBar.progress = clamp01(loadCount/maxLen);
console.log(`预加载的资源:${path}, 进度${this.loadBar.progress}`);
if (loadCount >= maxLen) {
setTimeout(() => {
this.desc.string = "加载完成";
// 切换场景,进入主页面
director.loadScene("uiMain");
}, 1000);
}
}
);
}
}
}
效果图如下:
更多详情可参考:cocosCreator 资源管理
理解可能有误,欢迎大佬指出!感激不尽!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。