Unity 打包 AssetBundle

时间:2024-03-27 18:16:02

打包出的AssetBundle区分平台  (windows  android  ios)

通过打出来的AssetBundle对应的Hash值来判断该资源是否有更新(没有改动的资源重新打包Hash是不会变得啦)

需要保存在文件中的值: AssetBundle名称、 AssetBundle的Hash 、AssetBundle的依赖项


第一步:在Unity中设置你要打包成AssetBundle的资源 例如 我要打包这三项

Unity 打包 AssetBundle

他们在Inspector面板最下方的AssetBundle名称分别是(若果没有设置的话点New 直接输入就好了)

Unity 打包 AssetBundle

textures/icon.imgz

materials/mater.matz

prefabs/sphere.prez

值得一提的是...这里的AssetBundle名称是不区分大小写的

第二步:写代码!编写编辑器扩展的代码

创建一个脚本 取名BuildAssets

添加引用 --using UnityEditor;

这里以Windows编辑器环境为例 (也就是Unity环境啦)

public class BuildAssets

{

//在Unity的菜单栏中写个按钮-按钮执行BuildAllAssetBundlesForWindow方法(这里属于Unity编辑器扩展的知识)

    [MenuItem("Build/BuildAsse tBundles/Windows")] 
    static void BuildAllAssetBundlesForWindows()
    {
        ChoosePlatform(RuntimePlatform.WindowsEditor);

    }


    private static void ChoosePlatform(RuntimePlatform platform)

    {

        //这个路径就是  打包后AssetBundle存放的路径

        //其实这个path最终的结果是 "Assets/AssetBundles/windows/"

        string path = assetBundleDirectory + GetPlatformName(platform);

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);

        }


        int option = EditorUtility.DisplayDialogComplex("Build AssetBundles For " + GetPlatformName(platform), "是否打包AssetBundles在" + GetPlatformName(platform) + "平台", "是", "否", "取消");
        switch (option)
        {
            case 0:

         Build(platform);//划重点!重要的函数加粗..打包的核心函数

                break;
            case 1:
            case 2:
                Debug.Log("Cancel build");
                break;


            default:
                Debug.LogError("Unrecognized option.");
                break;
        }

    }

//重点函数在这

private static void Build(RuntimePlatform platform)

    {

        //其实这个path最终的结果是 "Assets/AssetBundles/windows/"

        string path = assetBundleDirectory + GetPlatformName(platform);

        //DirPath  这个东西其实就是 "windows"

        string DirPath = Path.GetFileName(path);

        //这里的ResFile 其实就是打包后输出打包的信息To JSON之后保存为文件用的啦

        //这里的GlobalConst.Res.ResVersionFileName 其实就是"ResVersion.json"

        string ResFile = path + "/" + GlobalConst.Res.ResVersionFileName;
        //本地资源信息 (这里是为了比对版本升级版本号用的,测试的话可以删去相关代码)
        List<AssetBundleInfo> LocalResList = GetLocalResVersion(platform);

        //AssetBundle信息

        //AssetBundleInfo其实就是一个自定义类 重写了一些东西  其实测试的话只写几个字段就好啦

   /* public class AssetBundleInfo
    {
        public string Name;
        public string FileName;
        public string Hash;
        public string Version;
        public string[] Dependencies;
        public override bool Equals(object obj)
        {
            AssetBundleInfo ab = obj as AssetBundleInfo;
            return ab != null && 
                string.Compare(this.Name, ab.Name, true) == 0 &&
                string.Compare(this.Version, ab.Version, true) == 0;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }


        public override string ToString()
        {
            return "名称:" + this.Name + "文件名:" + FileName + "  Hash:" + this.Hash + "   版本:" + this.Version;
        }


    }*/

        List<AssetBundleInfo> ResList = new List<AssetBundleInfo>();
        //CRC文件校验码(这个东西是打包完成后 最终的输出目录下会有一个"目录名.manifest"的文件中的CRC码)
        uint CRC = 0;

//这个GetPlatform(platform) 直接填 BuildTarget.StandaloneWindows64 就好啦

//这个函数是打包的核心函数 Unity提供的API(反正是官方文档上写的)

//打包后 会返回一系列的信息 都存在assetBundleManifest 啦  可以用这个东西获取很多信息

//执行了下面这个函数 如果不报错的话 应该会在你刚才写的目录下打包完成了!!

 AssetBundleManifest assetBundleManifest = BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, GetPlatform(platform));

       //下面这些代码emmmmm看看就好了  主要用来将AssetBundleManifest的信息输出到文件

        string[] assetBundleNames = assetBundleManifest.GetAllAssetBundles();
        foreach (var assetBundleName in assetBundleNames)
        {
            var Res = new AssetBundleInfo();
            Res.Name = Path.GetFileName(path + "/" + assetBundleName);
            Res.FileName = assetBundleName;
            Res.Hash = assetBundleManifest.GetAssetBundleHash(assetBundleName).ToString();
            Res.Dependencies = assetBundleManifest.GetDirectDependencies(assetBundleName);
            //版本校验
            var LocalResItem = LocalResList.Find(item => item.FileName == Res.FileName);
          Res.Version = ((LocalResItem.Hash == Res.Hash) ? LocalResItem.Version : GameVersion.UpdateVersion2Str(2, LocalResItem.Version));
            
            Debug.Log(Res.ToString());
            ResList.Add(Res);
        }




        BuildPipeline.GetCRCForAssetBundle(path+"/"+ DirPath, out CRC);
        string json = LitJson.JsonMapper.ToJson(ResList);


        if (File.Exists(ResFile))
        {
            File.Delete(ResFile);
        }
        File.WriteAllText(ResFile, json);
       
    }


}

到这里就打包完成啦!~~~~~~~~~~~~~~~~~~

Unity 打包 AssetBundle