美文网首页程序员
AssetBundle打包学习(一)

AssetBundle打包学习(一)

作者: carber | 来源:发表于2016-11-03 15:59 被阅读1020次

    AssetBundle是Unity支持的一种资源打包方式。区别于Resources目录的打包资源,AssetBundle可以更加方便灵活的定制自己的资源组织方式,也可以支持资源更新。

    AssetBundle 打包

    AssetBundle打包以Object为单位,我们可以通过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内置的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来管理打包,同层之间的资源也是依赖的(先打的包有的,后面包就不会再打了),这里要比较小心不然依赖关系容易乱。
    之前提到的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简化了打包过程,只需要设置BundleName,然后Build即可。
    Unity 5支持在Inspect界面给每个资源设定BundleName,比起代码设置多了一种管理途径。

    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");
    }
    

    总结

    Unity提供了丰富的接口便于我们去构建AssetBundle,不过构建大小合理依拉关系清晰的AssetBundle还需要下较大的功夫去分析资源之间的依赖关系。
    对比Unity 5新的打包方式,可以发现老接口可以更加精确的控制资源打包的力度,而且对于类似Unity内置Shader这种无路径内置对象,5只能通过替换Shader为本地的有路径Shader来做,不够灵活

    AssetBundle压缩格式介绍

    相关文章

      网友评论

        本文标题:AssetBundle打包学习(一)

        本文链接:https://www.haomeiwen.com/subject/jtamuttx.html