5.Eric-MVVM-Framework-资源管理器
- 创建解析器解析分包名和资源路径
因为之前设计了分包管理器,所以默认资源加载是分包处理。
这里创建一个解析分包名和路径名的工具类。
/**
* 解析器
* 提供路径解析功能。
*/
export class Parser {
/**
* 解析资源路径并将其分解为包名和路径
*
* @param resPath - 要解析的资源路径
* @returns 返回包含 bundleName 和 path 的对象
*/
public static path(resPath: string): { bundleName: string; path: string } {
const [bundleName, ...pathParts] = resPath.split('/');
return {
bundleName,
path: pathParts.join('/')
};
}
}
- 创建资源管理类ResMgr
/**
* 资源管理器
* 提供资源加载、释放功能。
*/
import { Asset, AssetManager, assetManager } from "cc";
import { Parser } from "../Utils/Parser";
class ResMgr {
/** 私有构造函数,确保外部无法直接通过new创建实例 */
private constructor() {}
/** 单例实例 */
public static readonly instance: ResMgr = new ResMgr();
/**
* 加载资源
* @param resPath 资源路径
* @param progressFun 进度回调函数
* @param completeFun 完成回调函数
* @returns Promise<T> 加载完成后的Promise
*/
public async loadRes<T extends Asset>(
resPath: string,
progressFun?: (completedCount: number, totalCount: number, item: any) => void,
completeFun?: (err: Error | null, asset: T) => void
): Promise<T> {
try {
const { bundleName, path } = Parser.path(resPath);
const bundle = await eric.bundle.getBundle(bundleName);
return await this.loadAsset<T>(bundle, path, progressFun, completeFun);
} catch (error) {
eric.log.err(`加载资源失败: ${resPath}`, error.message);
throw error;
}
}
/**
* 加载目录下的所有资源
* @param resPath 资源路径
* @param progressFun 进度回调函数
* @param completeFun 完成回调函数
* @returns Promise<Array<Asset>> 加载完成后的Promise
*/
public async loadResDir(
resPath: string,
progressFun?: (completedCount: number, totalCount: number, item: any) => void,
completeFun?: (err: Error | null, assets: Array<Asset>) => void
): Promise<Array<Asset>> {
try {
const { bundleName, path } = Parser.path(resPath);
const bundle = await eric.bundle.getBundle(bundleName);
return await this.loadAssetDir(bundle, path, progressFun, completeFun);
} catch (error) {
eric.log.err(`加载目录失败: ${resPath}`, error.message);
throw error;
}
}
/**
* 释放指定分包单个资源
* @param resPath 资源路径
*/
public releaseRes(resPath: string): void {
const { bundleName, path } = Parser.path(resPath);
const bundle = assetManager.getBundle(bundleName);
if (bundle) {
bundle.release(path);
} else {
eric.log.err(`分包 ${bundleName} 未找到,无法释放资源 ${path}。`);
}
}
/**
* 释放指定分包全部资源
* @param bundleName 分包名称
*/
public releaseBundle(bundleName: string): void {
const bundle = assetManager.getBundle(bundleName);
if (bundle) {
bundle.releaseAll();
assetManager.removeBundle(bundle);
} else {
eric.log.err(`分包 ${bundleName} 未找到,无法移除。`);
}
}
/** 移除所有分包 */
public releaseAll(): void {
assetManager.releaseAll();
}
/**
* 加载单个资源的辅助方法
* @param bundle 资源所在的分包
* @param path 资源路径
* @param progressFun 进度回调函数
* @param completeFun 完成回调函数
* @returns Promise<T> 加载完成后的Promise
*/
private loadAsset<T extends Asset>(
bundle: AssetManager.Bundle,
path: string,
progressFun?: (completedCount: number, totalCount: number, item: any) => void,
completeFun?: (err: Error | null, asset: T) => void
): Promise<T> {
return new Promise<T>((resolve, reject) => {
bundle.load(
path,
(completedCount, totalCount, item) => progressFun?.(completedCount, totalCount, item),
(err, asset) => {
completeFun?.(err, asset as T);
if (err) {
eric.log.err(`从分包加载资源 ${path} 失败`, err.message);
reject(err);
} else {
resolve(asset as T);
}
}
);
});
}
/**
* 加载目录下所有资源的辅助方法
* @param bundle 资源所在的分包
* @param path 目录路径
* @param progressFun 进度回调函数
* @param completeFun 完成回调函数
* @returns Promise<Array<Asset>> 加载完成后的Promise
*/
private loadAssetDir(
bundle: AssetManager.Bundle,
path: string,
progressFun?: (completedCount: number, totalCount: number, item: any) => void,
completeFun?: (err: Error | null, assets: Array<Asset>) => void
): Promise<Array<Asset>> {
return new Promise<Array<Asset>>((resolve, reject) => {
bundle.loadDir(
path,
(completedCount, totalCount, item) => progressFun?.(completedCount, totalCount, item),
(err, assets) => {
completeFun?.(err, assets);
if (err) {
eric.log.err(`从分包加载目录 ${path} 失败`, err.message);
reject(err);
} else {
resolve(assets);
}
}
);
});
}
}
-
建立映射
-
测试
/**
- 源码作者:
*/
import { _decorator, Component, Node, Prefab } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('Test')
export class Test extends Component {
protected onLoad(): void {
const onProgress = (completedCount: number, totalCount: number,item:any) => {
eric.log.info("加载进度",${(completedCount/totalCount*100).toFixed(2)}%);
}
const onComplete = (error: Error | null, asset: any) => {
if (error) {
eric.log.info("加载完成", "失败");
} else {
eric.log.info("加载完成", "成功");
}
};
eric.res.loadRes<Prefab>("Prefab/Test", onProgress, onComplete)
.then((asset)=>{
console.log("测试资源加载完成",asset);
})
}
}
浙公网安备 33010602011771号