KEngine:Unity3D資源的打包、加載、調試監控


資源模塊做什么?

資源模塊——ResourceModule,是KEngine中最核心的模塊,其他模塊基本或多或少的對它有依賴,它主要的功能是:資源打包、路徑定義、資源管理、資源調試

資源模塊對Unity的Asset Bundle接口進行了完整的封裝,運行模式下可以使用它進行完整的資源加載、卸載,也可以通過它方便地查找資源內存泄露的問題。

AssetBundle自動化打包

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

1835687-f321afec78c28857

圖:把需要打包的資源放到BundleResources目錄中

 

1835687-3dc5b149ffbe865a

圖:AssetBundle最終默認生成到Product/Bundles/(Platform)/中

 

1835687-017b666adb7a1b54

圖: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中的LoadBundleLoadBundleAsync接口,可以實現類似於Unity的Resources.LoadResources.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中定義了各種類型的資源加載器,提供更為方便的加載、調試功能,來避免一些使用上的。坑

Loader加載器

加載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,只用於進行調試、內存信息查看:

1835687-d3ce2681c5d480ee

圖:資源加載調試信息:Loader、加載的對象

 

1835687-da5e24f6ff4801ec

圖:每一個Loader的引用計數信息,都可以通過面板來進行實時查看

 

如上圖所示,通過KEngine的資源調試器,可以方便的找到加載的AssetBundle的資源對象、監控內存占用的大小、Loader加載消耗的時間、Loader當前引用計數等信息。對比Unity原生的Profiler,這些信息是即時的。 開發人員可以非常方便的尋找資源泄露問題,優化內存占用。

 

版權說明

文/公的Kelly[mr-kelly](簡書作者)     Email: 23110388@qq.com
原文鏈接:http://www.jianshu.com/p/ce3b5d0bdf8c
著作權歸作者所有,轉載請聯系作者獲得授權,,並標注“簡書作者”。

 

KSFramework系列

github地址:https://github.com/mr-kelly/KSFramework

歡迎大家到 github提issues

 

KSFramework(集成U3D熱重載)README

KSFramework:Unity3D開發框架快速入門

KEngine策划指南:配置表格的編輯與編譯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM