KEngine资源的打包、加载、调试监控

KSFramework是一个Unity 5 Asset Bundle开发框架和工具集,专注于运行时热重载,使用了SLua作为脚本引擎。

资源模块做什么?

资源模块——ResourceModule,是KEngine中最核心的模块,其他模块基本或多或少的对它有依赖,它主要的功能是:资源打包、路径定义、资源管理、资源调试

资源模块对Unity的Asset Bundle接口进行了完整的封装,运行模式下可以使用它进行完整的资源加载、卸载,也可以通过它方便地查找资源内存泄露的问题。

AssetBundle自动化打包

Unity 5中,Asset Bundle系统做了很大的变化。你只需将需要打包的资源配置AssetBundle Name,然后执行接口BuildPipeline.BuildAssetBundles(outputPath)就完成了所有AssetBundle的打包,比Unity 4.x方便多了。

把需要打包的资源放到BundleResources目录中
AssetBundle最终默认生成到Product/Bundles/(Platform)/中
KEngine->AssetBundle->Build All,自动设置BundleResources目录下所有的资源的Asset Bundle Name并执行打包

在KEngine+Unity 5.x中,把配置AssetBundle Name的这一步也省掉了。你只需把需要打包的资源,放在Assets/BundleResources目录中,所有的AssetBundle将会完整导出。

路径定义

Unity跨平台开发中,针对不同的平台——如编辑器、安卓、IOS、Windows等,一般有不同的资源存放路径。

像生成的Asset Bundle,还需要针对不同的平台,生成完全不一样的Asset Bundle资源。

因而KEngine中分别对Unity中的StreamingAssetsPath、PersistentDataPath等做了封装,开发人员无需为资源放在什么目录进行烦恼了(详见ResourceModule中的InitResourcePath方法),并且,内置了支持热更新。

举例:加载一个Asset Bundle的路径选择

假设现在要加载一个UI资源"Login":

        public IEnumerator LoadUIAsset(CUILoadState loadState, UILoadRequest request)
        {
            string path = string.Format("ui/login.prefab.bytes"));
            var assetLoader = KStaticAssetLoader.Load(path);
            while (!assetLoader.IsCompleted)
                yield return null;

            request.Asset = assetLoader.TheAsset;  // Asset 是GameObject
        }

这个StaticAssetLoader,做了什么操作?假设我们在Android平台

  • 获知ui/login.prefab.bytes这个路径
  • 寻找热更新资源,尝试加载PersistentAssetsPath/Bundles/Android/ui/logins.prefabs.bytes
  • 无法找到热更新资源,尝试加载StreamingAssetsPath/Bundles/Android/ui/logins.prefabs.bytes
  • 依然无法找到,加载失败

资源加载

KEngine在Unity 5.x中,会自动的先加载依赖资源,你只要填入Asset Bundle的路径名字就可以了。就像Unity的Resources类一样。

简单加载

使用ResourceModule中的LoadBundle、LoadBundleAsync接口,可以实现类似于Unity的Resources.Load、Resources.LoadAsync的效用。

要注意的是,LoadBundle、LoadBundleAsync接口,起始地址是加载StreamingAssets/Bundles/Win32或StreamingAssets/Bundles/Android这种平台相关的路径。

// 同步加载,返回加载器,加载器中有加载的资源
var reqeust = ResourceModule.LoadBundle("ui/login.prefab.bytes")
Debug.Log(request.Asset != null); // true

// 异步加载,返回加载器,加载器中还没加载的资源,需要异步等待
var request = ResourceModule.LoadBundleAsync("ui/login.prefab.bytes", (isOk, asset, args)=>{});
Debug.Log(request.Asset == null); // true

Loader加载器

KEngine中定义了各种类型的资源加载器,提供更为方便的加载、调试功能,来避免一些使用上的。坑

加载GameObject

最常用的Loader有两个:

  • StaticAsset:每次调用Load,使用同一份GameObject引用
  • InstanceAsset:每次调用Load,都会拷贝出一份GameObject
       // 协程风格
        public IEnumerator LoadUIAsset(UILoadRequest request)
        {
            string path = string.Format("ui/login.prefab.bytes"));
            var assetLoader = KStaticAssetLoader.Load(path);
            while (!assetLoader.IsCompleted)
                yield return null;

            request.Asset = assetLoader.TheAsset;  // Asset 是GameObject
        }
       // CPS回调风格
        public void LoadUIAsset(UILoadRequest request)
        {
            string path = string.Format("ui/login.prefab.bytes"));
            KStaticAssetLoader.Load(path, (isOk, asset, args)=>{
                request.Asset =asset; 
            });
        }

资源的释放

KEngine中的资源释放,跟Unity的资源释放明显区别是:Unity中提供Resources.UnloadUnusedAssets接口,来自动释放无用的资源的。而KEngine中资源释放采用纯手动的方式。

这主要是因为躺过Unity自动释放资源的很多坑: 经常会遇到“missing”的资源引用吧?因此选择了手动释放机制。

所有XXXLoader,都有一个接口Loader.Release(),举例:

            string path = string.Format("ui/login.prefab.bytes"));
            var assetLoader = KStaticAssetLoader.Load(path);  // 引用计数1
            while (!assetLoader.IsCompleted)
                yield return null;
            var assetLoader2 = KStaticAssetLoader.Load(path);  // 引用计数2
            while (!assetLoader2.IsCompleted)
                yield return null;

            assetLoader2.Release(); // 释放,减小引用计数  // 引用计数1
            assetLoader.Release(); // 引用计数0,正式删掉缓存的资源

手工释放的资源存在引用计数,只有当引用计数为0,Loader才会触发回收,并且连同加载过的AssetBundle彻底消灭,节省内存。

其它Loader

诸如TextureLoader、AudioLoader等等,所有XXXLoader的使用方法都是一致的,它们提供CPS回调风格和协程风格

资源的调试监控

在Unity Editor模式下,所有的XXXLoader加载类实例,都会伴随住一个GameObject的产生,而这个GameObject,只用于进行调试、内存信息查看:

资源加载调试信息:Loader、加载的对象
每一个Loader的引用计数信息,都可以通过面板来进行实时查看

如上图所示,通过KEngine的资源调试器,可以方便的找到加载的AssetBundle的资源对象、监控内存占用的大小、Loader加载消耗的时间、Loader当前引用计数等信息。对比Unity原生的Profiler,这些信息是即时的。 开发人员可以非常方便的寻找资源泄露问题,优化内存占用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容