You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
421 lines
15 KiB
421 lines
15 KiB
import { AssetManager, assetManager, resources, Prefab, sp, SpriteFrame, TiledMapAsset, Asset, instantiate, Node, AudioClip, VideoClip, SpriteAtlas, TextAsset, BufferAsset, __private } from "cc";
|
|
import { PREVIEW } from "cc/env";
|
|
import { EResUrls } from "./EResUrls";
|
|
import ResourceMemoryChecker from "../CComEx/ResourceMemoryChecker";
|
|
import { EBundleName } from "../const/GameEnum";
|
|
import { Utils } from "../ExUtils/Utils";
|
|
import CocosUtils from "../ExCUtils/CocosUtils";
|
|
import { TDAnalyticsMgr } from "../Mgr_Ge/TDAnalyticsMgr";
|
|
import { GEData } from "../Mgr_Ge/GeDifine";
|
|
|
|
type _types_globals__Constructor<T = unknown> = new (...args: any[]) => T;
|
|
export type CCAssetType<T = Asset> = _types_globals__Constructor<T>;
|
|
/**函数类型 */
|
|
type BackBundleType = (err: Error | null, res: AssetManager.Bundle) => void;
|
|
|
|
/**加载资源 返回函数类型 */
|
|
type LoadType<T extends Asset | Asset[]> = (err: Error | null, res: T | T[]) => void;
|
|
|
|
/**预加载 返回函数类型 */
|
|
type preLoadType = (res: boolean) => void;
|
|
|
|
/**预加载定义 */
|
|
interface preLoadInfo {
|
|
bundle: string | EBundleName,
|
|
preUIPrefab?: boolean,
|
|
preDir?: string[],
|
|
Dir?: string[],
|
|
ui?: string[],
|
|
pres?: string[],
|
|
Atlas?: string[],
|
|
AtlasAll?: boolean,
|
|
Spine?: string[],
|
|
SpineAll?: boolean,
|
|
}
|
|
|
|
/**
|
|
* 资源加载类
|
|
*/
|
|
export default class ResLoad {
|
|
private static _ins: ResLoad = null;
|
|
public static allDoen = false;
|
|
public static get Ins(): ResLoad {
|
|
if (!this._ins) { this._ins = new ResLoad(); }
|
|
return this._ins;
|
|
}
|
|
/**常驻Bundle 不可释放*/
|
|
private PBundles: EBundleName | string[] = [
|
|
EBundleName.Presets,
|
|
EBundleName.resources,
|
|
EBundleName.General,
|
|
];
|
|
/**预加载Bundle */
|
|
private preLoadBundlelist: preLoadInfo[] = [];
|
|
private preSecondBundlelist: preLoadInfo[] = [];
|
|
/**预加载Bundle的数量 */
|
|
private preLoadBundleCount: number = 0;
|
|
/**预加载Bundle完毕回调 */
|
|
private preLoadBundleComplete: () => void;
|
|
/**加载bundle */
|
|
async loadBundle(BundleName: EBundleName | string, onComplete?: BackBundleType) {
|
|
const res = await this.loadBundleAsync(BundleName);
|
|
onComplete && onComplete(null, res);
|
|
}
|
|
async loadBundleAsync(BundleName: EBundleName | string) {
|
|
return new Promise<AssetManager.Bundle>((resolve, reject) => {
|
|
let bundle = assetManager.getBundle(BundleName);
|
|
if (bundle) {
|
|
resolve(bundle);
|
|
} else {
|
|
let tempTime = performance.now();
|
|
assetManager.loadBundle(BundleName, (err, bundle: AssetManager.Bundle) => {
|
|
if (err) {
|
|
resolve(null);
|
|
} else {
|
|
let offsetTime = performance.now() - tempTime;
|
|
ConsoleEx.Warn(`${BundleName} 包加载耗时`, offsetTime);
|
|
// TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.load_bundle, { bundle: BundleName, duration: Utils.MathUtils.MsToFloat(offsetTime) })
|
|
resolve(bundle);
|
|
}
|
|
})
|
|
}
|
|
});
|
|
}
|
|
|
|
ReleaseAll(list: string[]) {
|
|
assetManager.bundles.forEach((value, key) => {
|
|
if (!list.includes(key) && !this.PBundles.includes(key)) {
|
|
value.releaseAll();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**释放bundle资源 */
|
|
Release(name: EBundleName | string) {
|
|
if (assetManager.bundles.has(name) && !this.PBundles.includes(name)) {
|
|
assetManager.bundles.get(name).releaseAll();
|
|
}
|
|
}
|
|
|
|
InitLoadBundleList() {
|
|
this.preLoadBundlelist = [];
|
|
this.preSecondBundlelist = [];
|
|
let _keys: string[] = Object.keys(EBundleName);
|
|
for (let _key of _keys) {
|
|
//先删除ts枚举自带的反向映射
|
|
if (/^[0-9]+$/.test(_key)) {
|
|
} else {
|
|
if (_key == EBundleName.resources) {
|
|
continue;
|
|
}
|
|
let tData: preLoadInfo = { bundle: _key, preUIPrefab: true };
|
|
// tData.preDir = ["Texture"];
|
|
// tData.preUIPrefab = false;
|
|
if(_key == EBundleName.Presets || _key == EBundleName.General || _key == EBundleName.Game){
|
|
this.preLoadBundlelist.push(tData);
|
|
}else{
|
|
this.preSecondBundlelist.push(tData);
|
|
}
|
|
// this.preLoadBundlelist.push(tData);
|
|
}
|
|
}
|
|
// this.preLoadBundleCount = this.preLoadBundlelist.length;
|
|
// this.startLoadBundleList(this.preLoadBundlelist);
|
|
}
|
|
|
|
// preLoadSpineAsset(urls: string[]){
|
|
// let loadtime = Date.now();
|
|
// let assets: string[] = [];
|
|
// for (let i = 0; i < urls.length; i++) {
|
|
// assets.push(EResUrls.Spine(`${urls[i]}/${urls[i]}`));
|
|
// }
|
|
// if(assets.length > 0){
|
|
// this.loadBundleAsync(EBundleName.Spine).then((bundle) => {
|
|
// bundle.preload(urls, (e2, res) => {ConsoleEx.Com("Spine资源预加载成功:", urls, " 耗时:",Date.now() - loadtime)});
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
InitFirstBundleList(compallcallback) {
|
|
this.preLoadBundleComplete = compallcallback;
|
|
this.preLoadBundleCount = this.preLoadBundlelist.length;
|
|
this.startLoadBundleList(this.preLoadBundlelist);
|
|
}
|
|
InitSecendBundleList() {
|
|
this.preLoadBundleCount = this.preSecondBundlelist.length;
|
|
this.startLoadBundleList(this.preSecondBundlelist);
|
|
ResLoad.allDoen = true;
|
|
}
|
|
|
|
startLoadBundleList(preBundlelist) {
|
|
// this.preLoadBundleComplete = compallcallback;
|
|
// while (preBundlelist.length > 0) {
|
|
this.LoadBundleList(preBundlelist);
|
|
// }
|
|
}
|
|
|
|
|
|
private async LoadBundleList(preBundlelist) {
|
|
if (preBundlelist.length <= 0) {
|
|
// ResLoad.allDoen = true;
|
|
return;
|
|
}
|
|
let tpreData = preBundlelist.shift();
|
|
this.loadBundle(tpreData.bundle, (e, bundle: AssetManager.Bundle) => {
|
|
if (--this.preLoadBundleCount <= 0) {
|
|
// ResLoad.allDoen = true;
|
|
this.preLoadBundleComplete && this.preLoadBundleComplete();
|
|
}
|
|
if (e) {
|
|
this.LoadBundleList(preBundlelist);
|
|
return;
|
|
}
|
|
let urls: string[] = [];
|
|
for (let i = 0; i < tpreData.ui?.length; i++) {
|
|
urls.push(EResUrls.UIPrefabs(tpreData.ui[i]));
|
|
}
|
|
|
|
|
|
for (let i = 0; i < tpreData.pres?.length; i++) {
|
|
urls.push(EResUrls.Prefabs(tpreData.pres[i]));
|
|
}
|
|
|
|
for (let i = 0; i < tpreData.Atlas?.length; i++) {
|
|
//urls.push(EResUrls.Atlas(tpreData.Atlas[i]));
|
|
}
|
|
|
|
// for (let i = 0; i < tpreData.Spine?.length; i++) {
|
|
// urls.push(EResUrls.Spine(`${tpreData.Spine[i]}/${tpreData.Spine[i]}`));
|
|
// }
|
|
|
|
for (let i = 0; i < tpreData.Dir?.length; i++) {
|
|
bundle.loadDir(tpreData.Dir[i], (err, res) => {
|
|
PREVIEW && ConsoleEx.Com("路径加载完成", tpreData.bundle, tpreData.Dir[i])
|
|
})
|
|
}
|
|
|
|
for (let i = 0; i < tpreData.preDir?.length; i++) {
|
|
bundle.preloadDir(tpreData.preDir[i], (err, res) => {
|
|
PREVIEW && ConsoleEx.Com("路径加载完成", tpreData.bundle, tpreData.preDir[i])
|
|
})
|
|
}
|
|
|
|
if (tpreData.AtlasAll) {
|
|
bundle.preloadDir("Atlas", (err, res) => {
|
|
PREVIEW && ConsoleEx.Com("预加载图集完成", tpreData.bundle)
|
|
})
|
|
}
|
|
|
|
if (tpreData.preUIPrefab) {
|
|
bundle.preloadDir("UIPrefabs", (err, res) => {
|
|
PREVIEW && ConsoleEx.Com("预加载UI资源完成", tpreData.bundle)
|
|
})
|
|
}
|
|
|
|
|
|
if (urls.length <= 0) {
|
|
this.LoadBundleList(preBundlelist);
|
|
return;
|
|
}
|
|
|
|
bundle.preload(urls, (e2, res) => {
|
|
if (PREVIEW) {
|
|
let list: string[] = [];
|
|
for (let i = 0; i < res.length; i++) {
|
|
const tRes = res[i];
|
|
let bundleName = tpreData.bundle
|
|
const tBundle = CocosUtils.GetResBundle(tRes.uuid)
|
|
if (tBundle) {
|
|
bundleName = tBundle.name as EBundleName;
|
|
}
|
|
let path = CocosUtils.GetResBundlePath(tRes.uuid);
|
|
if (path == "") {
|
|
path = tRes.uuid;
|
|
}
|
|
list.push(`${bundleName} ${path}`);
|
|
}
|
|
ConsoleEx.Com(tpreData.bundle, list)
|
|
}
|
|
this.LoadBundleList(preBundlelist);
|
|
})
|
|
});
|
|
}
|
|
|
|
|
|
/**根据名称 获取一个Bundle */
|
|
getBundle(BundleName?: string) {
|
|
var bundle = assetManager.bundles.get(BundleName);
|
|
if (bundle) {
|
|
return bundle;
|
|
}
|
|
if (PREVIEW) {
|
|
if (BundleName && BundleName != "resources") {
|
|
ConsoleEx.Warn("未找到目标Bundle", BundleName)
|
|
}
|
|
}
|
|
return resources;
|
|
}
|
|
|
|
async Perfab(url: string, bundle: EBundleName | string, callBack?: (error: Error, assets: Prefab) => void) {
|
|
this.Load(url, bundle, Prefab, callBack);
|
|
}
|
|
|
|
PrePerfab(url: any, bundle: string, callBack?: preLoadType) {
|
|
this.preLoad(url, bundle, Prefab, callBack);
|
|
}
|
|
|
|
/**预加载spine资源 */
|
|
PreSpine(url: any, bundle: string, callBack?: preLoadType) {
|
|
this.preLoad(url, bundle, sp.SkeletonData, callBack);
|
|
}
|
|
|
|
/**预加载Sprite资源 */
|
|
PreSprite(url: any, bundle: string, callBack?: preLoadType) {
|
|
this.preLoad(url + "/spriteFrame", bundle, SpriteFrame, callBack);
|
|
}
|
|
|
|
/**加载spine文件 */
|
|
Spine(url: any, bundle: string, callBack?: (error: Error, assets: sp.SkeletonData) => void) {
|
|
this.Load(url, bundle, sp.SkeletonData, callBack);
|
|
}
|
|
|
|
/**加载spritefame */
|
|
public Sprite(url: string, bundle: string, callBack?: (error: Error, assets: SpriteFrame) => void) {
|
|
this.Load(url + "/spriteFrame", bundle, SpriteFrame, callBack);
|
|
}
|
|
|
|
/**加载AudioClip */
|
|
public PreDirAudioClip(url: any, bundle: string, callBack?: (error: Error, assets: AudioClip[]) => void) {
|
|
this.getBundle(bundle).preloadDir(url, AudioClip);
|
|
}
|
|
|
|
/**加载AudioClip */
|
|
public AudioClip(url: string, bundle: string, callBack?: (error: Error, assets: AudioClip) => void) {
|
|
this.Load(url, bundle, AudioClip, callBack);
|
|
}
|
|
|
|
/**加载SpriteAtlas */
|
|
public AutoAtlas(url: any, bundle: string, callBack?: (error: Error, assets: SpriteAtlas) => void) {
|
|
this.Load(url, bundle, SpriteAtlas, callBack);
|
|
}
|
|
|
|
/**
|
|
* 加载资源
|
|
* @param urls 资源路径列表
|
|
* @param model 加载模式
|
|
* @param onCompleted 完成时回调
|
|
* @param _onProgress 加载进度
|
|
*/
|
|
public Load<T extends Asset>(urls: string | string[], model: EBundleName | string, type: CCAssetType<T>, onComplete?: LoadType<T>, onProgress?: (finish?: any, total?: any, item?: any) => void) {
|
|
this.LoadAsync(urls, model, type, onProgress).then((res) => { onComplete && onComplete(null, res as any); })
|
|
}
|
|
|
|
/**
|
|
* 加载资源
|
|
* @param urls 资源路径列表
|
|
* @param model 加载模式
|
|
* @param onCompleted 完成时回调
|
|
* @param _onProgress 加载进度
|
|
*/
|
|
public preLoad<T extends Asset>(urls: string | string[], model: EBundleName | string, type: CCAssetType<T>, onComplete?: preLoadType, onProgress?: (finish?: any, total?: any, item?: any) => void) {
|
|
this.preLoadAsync(urls, model, type, onProgress).then((res) => { onComplete && onComplete(res); })
|
|
}
|
|
|
|
/**
|
|
* 加载资源
|
|
* @param urls 资源路径列表
|
|
* @param model 加载模式
|
|
* @param onCompleted 完成时回调
|
|
* @param _onProgress 加载进度
|
|
*/
|
|
public async LoadAsync<T extends Asset>(urls: string | string[], bName: string, type: CCAssetType<T>, onProgress?: (finish?: any, total?: any, item?: any) => void) {
|
|
if (Array.isArray(urls)) {
|
|
//去除虚值
|
|
urls = urls.filter(Boolean);
|
|
}
|
|
let bundle = await this.loadBundleAsync(bName);
|
|
if (Array.isArray(urls)) {
|
|
return new Promise<T[]>((resolve, reject) => {
|
|
bundle.load(urls, type, onProgress, (err, res: T[]) => {
|
|
if (err) {
|
|
resolve(null);
|
|
} else {
|
|
resolve(res);
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
return new Promise<T>((resolve, reject) => {
|
|
bundle.load(urls, type, onProgress, (err, res: T) => {
|
|
if (err) {
|
|
resolve(null);
|
|
} else {
|
|
resolve(res);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 加载资源
|
|
* @param urls 资源路径列表
|
|
* @param model 加载模式
|
|
* @param onCompleted 完成时回调
|
|
* @param _onProgress 加载进度
|
|
*/
|
|
public async preLoadAsync<T extends Asset>(urls: string | string[], bName: string, type: CCAssetType<T>, onProgress?: (finish?: any, total?: any, item?: any) => void) {
|
|
if (Array.isArray(urls)) {
|
|
//去除虚值
|
|
urls = urls.filter(Boolean);
|
|
}
|
|
const bundle = await this.loadBundleAsync(bName);
|
|
if (!bundle) { ConsoleEx.Error("加载失败!", bName); return; }
|
|
if (Array.isArray(urls)) {
|
|
return new Promise<boolean>((resolve, reject) => {
|
|
bundle.preload(urls, type, onProgress, (err) => {
|
|
if (err) {
|
|
resolve(false);
|
|
} else {
|
|
resolve(true);
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
return new Promise<boolean>((resolve, reject) => {
|
|
bundle.preload(urls, type, onProgress, (err) => {
|
|
if (err) {
|
|
resolve(false);
|
|
} else {
|
|
resolve(true);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取资源
|
|
* @param resUrl 资源路径
|
|
* @param noClone 是否不获取克隆的资源
|
|
*/
|
|
public GetRes(resUrl: string, BundleName?: EBundleName | string, noClone: boolean = false, type = Asset): any {
|
|
if (!resUrl) { return ConsoleEx.Error(resUrl, "路径错误!") }
|
|
const Bundle: AssetManager.Bundle = this.getBundle(BundleName);
|
|
const getRes = Bundle.get(resUrl, type);
|
|
if (!getRes) {
|
|
ConsoleEx.Warn("资源尚未加载", resUrl);
|
|
return null;
|
|
}
|
|
return noClone ? getRes : instantiate(getRes);
|
|
}
|
|
|
|
public GetTextureMemory() {
|
|
console.log(ResourceMemoryChecker.generateMemoryReport())
|
|
}
|
|
|
|
}
|
|
|
|
if (PREVIEW) {
|
|
window['ResLoad'] = ResLoad;
|
|
}
|