【muzzik 教程】:框架 - 资源管理
实现功能
-
asset (资源管理器)
-
资源加载接口整合
-
编辑器资源加载
-
资源生命周期管理
-
-
bundle (bundle 管理器)
-
bundle 加载/重载
-
scene 加载
-
bundle 管理单元
-
asset (资源管理器)
资源加载接口整合
统一本地/远程/编辑器
资源加载接口为 get/get_dir
编辑器资源加载
// path_s_ 格式为 "db://assets/xxx"
const uuid_s = await Editor.Message.request("asset-db", "query-uuid", path_s_);
cc.assetManager.loadAny({ uuid: uuid_s }, completed_f);
资源生命周期管理
在游戏中经常会遇到短时间加载/卸载同一资源,所以针对这点进行优化
- 加载资源后引用计数 + 2
- 重载 decRef,在引用计数为 1 时加入释放表,释放表间隔批量释放
bundle (bundle 管理器)
bundle 加载
很简答,封装 cc.assetManager.loadBundle
为异步函数即可
bundle 重载
由于引擎没有实现 bundle 重载后的脚本资源更新,所以需要我们自己做
/** 重新加载 bundle */
async reload(info: Partial<bundle_.bundle_info>): Promise<cc.AssetManager.Bundle | null> {
if (PREVIEW) {
return null;
}
await this._engine_init_task;
/** bundle 信息 */
const bundle_info: bundle_.bundle_info = new bundle_.bundle_info(info)!;
/** bundle 脚本表 */
const bundle_script_tab: Record<string, any> = {};
/** js 系统 */
const system_js = self["System"];
/** 脚本缓存表 */
const script_cache_tab: Record<string, any> = system_js[Reflect.ownKeys(system_js).find((v) => typeof v === "symbol")];
// 更新 bundle 信息
this.add(bundle_info);
// 初始化 bundle 脚本表
Object.keys(script_cache_tab).forEach((v_s) => {
const current = script_cache_tab[v_s];
const parent = script_cache_tab[v_s].p;
const child = parent.d;
if (!parent || !child || current.id !== parent.id) {
return;
}
const name_s = parent.id.slice((parent.id as string).lastIndexOf("/") + 1);
bundle_script_tab[name_s] = parent;
});
// 清理脚本缓存
{
const bundle_root = bundle_script_tab[bundle_info.bundle_s];
if (bundle_root) {
bundle_root.d.forEach((v: { id: string }) => {
/** 脚本名 */
const name_s = v.id.slice((v.id as string).lastIndexOf("/") + 1, v.id.length - 3);
/** ccclass */
const ccclass = cc.js.getClassByName(name_s);
// 注销组件
if (ccclass) {
cc.js.unregisterClass(ccclass);
}
delete script_cache_tab[v.id];
delete system_js["registerRegistry"][v.id];
});
delete script_cache_tab[bundle_root.id];
delete system_js["registerRegistry"][bundle_root.id];
}
}
// 清理 bundle 资源
{
const bundle = cc.assetManager.getBundle(bundle_info.bundle_s);
if (bundle) {
bundle.releaseAll();
cc.assetManager.removeBundle(bundle);
}
}
// 加载 bundle
return this.load(bundle_info);
}
scene 加载
/** switch_scene 配置 */
export class switch_scene_config {
constructor(init_?: Partial<switch_scene_config>) {
Object.assign(this, init_);
}
/** bundle名(getBundle 时使用) */
bundle_s = "resources";
/** 预加载 */
preload_b?: boolean;
/** 加载回调 */
progress_callback_f?: (finish_n: number, total_n: number, item?: cc.AssetManager.RequestItem) => void;
/** 加载前调用的函数 */
before_load_callback_f?: cc.Director.OnBeforeLoadScene;
/** 启动后调用的函数 */
launched_callback_f?: cc.Director.OnSceneLaunched;
/** 场景卸载后回调 */
unloaded_callback_f?: cc.Director.OnUnload;
}
bundle 管理单元
...
标签:cocos,const,creator,cc,script,bundle,id,资源管理,加载 From: https://www.cnblogs.com/muzzik/p/17099273.html