AssetBundle打包學(xué)習(xí)(一)

AssetBundle是Unity支持的一種資源打包方式。區(qū)別于Resources目錄的打包資源,AssetBundle可以更加方便靈活的定制自己的資源組織方式,也可以支持資源更新。

AssetBundle 打包

AssetBundle打包以O(shè)bject為單位,我們可以通過Untiy接口加載資源引用到的所有資源去打包,也可以對這些資源做篩選。

public static bool BuildAssetBundle(
    UnityEngine.Object[] objs, string outputPath, out uint crc) {
    crc = 0;
    return BuildPipeline.BuildAssetBundle(null, objs,outputPath, out crc,
            BuildAssetBundleOptions.ChunkBasedCompression |
            BuildAssetBundleOptions.DeterministicAssetBundle |
            BuildAssetBundleOptions.CollectDependencies,
            BuildTarget.Android);
}

public static bool BuildAssetBundle(
    string[] assetsList, string outputPath,
    out uint crc , BundleType bundleType) {
    crc = 0;

    // Load all of assets in this bundle
    List<UnityEngine.Object> assets = new List<UnityEngine.Object>();
    foreach (string assetPath in assetsList) {
        UnityEngine.Object[] assetsAtPath = AssetDatabase.LoadAllAssetsAtPath(assetPath);
        assets.AddRange(assetsAtPath);
    }

    // assets include some not use object, we can filter used objects to reduce bundle size
    assets = FilterObjectByType(assets, bundleType);

    if (assets.Count == 0) {
        return false;
    }

    return BuildAssetBundle(assets.ToArray(), outputPath, out crc);
}

Shader資源打包

Unity內(nèi)置的Shader,并不能找到一個路徑去打包,這時候我們可以直接把Shader作為Object傳進去打包。

public static void BuildShaderBundle(string outputPath) {
    HashSet<string> shaderSet = new HashSet<string>();
    string[] files = Directory.GetFiles("Assets/", "*.mat", SearchOption.AllDirectories);
    for (int i = 0; i < files.Length; ++i) {
        Material material = AssetDatabase.LoadAssetAtPath<Material>(files[i]);
        if (material != null && material.shader != null &&
            !shaderSet.Contains(material.shader.name)) {
                shaderSet.Add(material.shader.name);
        }
    }

    List<UnityEngine.Object> shaderObjects = new List<UnityEngine.Object>();
    foreach (string shaderName in shaderSet) {
        shaderObjects.Add(Shader.Find(shaderName));
    }

    if (shaderObjects.Count == 0) return;

    uint crc = 0;
    BuildAssetBundle(shaderObjects.ToArray(), outputPath, out crc);
}

公用資源打包

考慮到不同的資源可能引用到相同的資源,比如兩個模型引用了相同的貼圖,如果這時候把兩個模型打成二個AssetBundle,那這張貼圖會被分別打到兩個AssetBundle里。
Unity提供里PushAssetDependencies和PopAssetDependencies來管理打包,同層之間的資源也是依賴的(先打的包有的,后面包就不會再打了),這里要比較小心不然依賴關(guān)系容易亂。
之前提到的Shader資源打包,可以做為共享包放在最頂層打包,這樣Shader就只有一份了。

public static void BuildAllBundles(List<string> commonTexture, List<string> modelList) {
    BuildPipeline.PushAssetDependencies();
    BuildShaderBundle("Bundle/Shader.assetbundle");

    foreach (string path in commonTexture) {
        BuildAssetBundle(path);
    }

    foreach (string path in modelList) {
        BuildPipeline.PushAssetDependencies();
        BuildAssetBundle(path);
        BuildPipeline.PopAssetDependencies();
    }

    BuildPipeline.PopAssetDependencies();
}

Unity 5 AssetBundle打包

Unity 5簡化了打包過程,只需要設(shè)置BundleName,然后Build即可。
Unity 5支持在Inspect界面給每個資源設(shè)定BundleName,比起代碼設(shè)置多了一種管理途徑。

public static void BuildAssetBuilds(string[] assetsPath) {
    for (int i = 0; i < assetsPath.Length; ++i) {
        AssetImporter asset = AssetImporter.GetAtPath(assetsPath[i]);
        asset.assetBundleName = Path.GetFileNameWithoutExtension(assetsPath[i]);
        asset.assetBundleVariant = "assetbundle";
        AssetDatabase.ImportAsset(assetsPath[i]);
    }
    AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

    BuildPipeline.BuildAssetBundles("Bundles");
}

總結(jié)

Unity提供了豐富的接口便于我們?nèi)?gòu)建AssetBundle,不過構(gòu)建大小合理依拉關(guān)系清晰的AssetBundle還需要下較大的功夫去分析資源之間的依賴關(guān)系。
對比Unity 5新的打包方式,可以發(fā)現(xiàn)老接口可以更加精確的控制資源打包的力度,而且對于類似Unity內(nèi)置Shader這種無路徑內(nèi)置對象,5只能通過替換Shader為本地的有路徑Shader來做,不夠靈活

AssetBundle壓縮格式介紹

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容