美文网首页
Unity-资源打包-AssetBundle

Unity-资源打包-AssetBundle

作者: 祝你万事顺利 | 来源:发表于2019-05-21 17:55 被阅读0次

    AB包定义作用

    1.压缩大小
    2.热更新使用

    使用流程

    对要打包的资源进行设置


    AB.PNG

    C#脚本不能打成AB包,因为C#在Unity中会编译成中间文件。

    参数相关

    Build的路径(随意只要是在硬盘上都可以的)
    BuildAssetBundleOptions
    BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用
    之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。
    在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。
    BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
    BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是
    我们可以加载指定资源而不用解压全部注意使用LZ4压缩,可以获得可以跟不压缩相媲美的加载速度,而且比不压缩文件要小。
    BuildTarget选择build出来的AB包要使用的平台

    创建AB包
    创建AB包,使用BuildPipeline类中的方法

        private static readonly string AbPath = Application.streamingAssetsPath;
        [MenuItem("Tools/CreateAB")]
        static void CreateAbPack()
        {
            BuildPipeline.BuildAssetBundles(AbPath, BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.Android);
            AssetDatabase.Refresh();
        }
    

    清除文件中的AB包

    [MenuItem("Tools/ClearABFile")]
        static void ClearAbPack()
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(AbPath);
            FileSystemInfo[] fileSystemInfo = directoryInfo.GetFileSystemInfos();
            foreach (FileSystemInfo item in fileSystemInfo)
            {
                if(item is DirectoryInfo)
                {
                    DirectoryInfo d = new DirectoryInfo(item.FullName);
                    d.Delete(true);
                }
                else
                {
                    item.Delete();
                }
            }
            AssetDatabase.Refresh();
        }
    

    读取AB包
    1.直接记载一个单独的物体(无依赖)
    通过AssetBundle的LoadFromFile方法获取AB包,在通过LoadAsset的泛型方法获得GameObject

        private string path;
        void Start () {
            path = Application.streamingAssetsPath;
            AssetBundle ab = AssetBundle.LoadFromFile(path + "/prefab");
            //print(ab);
            GameObject go = ab.LoadAsset<GameObject>("Sphere");
            Instantiate(go);
        }
    

    2.通过依赖加载,从本地进行加载

                path = Application.streamingAssetsPath;
                //从文件中加载StreamingAssets文件
                AssetBundle assetBundle = AssetBundle.LoadFromFile(path + "/StreamingAssets");
                //从StreamingAssets文件中获得AssetBundleManifest对象
                AssetBundleManifest assetBundleManifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
                //从AssetBundleManifest中加载一个AssetBundle对象的全部依赖
                string[] dps = assetBundleManifest.GetAllDependencies("prefab");
                //遍历依赖,加载所有的依赖
                for (int i = 0; i < dps.Length; i++)
                {
                    AssetBundle ab1 = AssetBundle.LoadFromFile(path + "/" + dps[i]);
                }
                AssetBundle ab = AssetBundle.LoadFromFile(path + "/prefab");
                GameObject go = ab.LoadAsset<GameObject>("Sphere");
                Instantiate(go);
    

    3.异步加载从文件中

    if (GUILayout.Button("异步加载"))
            {
                StartCoroutine(LoadAB(AbLoadBP));
            }
    
    IEnumerator LoadAB(Action action)
        {
            path = Application.streamingAssetsPath;
            AssetBundleCreateRequest assetBundle = AssetBundle.LoadFromFileAsync(path + "/prefab");
            yield return assetBundle;
            action();
        }
    

    4.从内存中加载
    异步:

        IEnumerator LoadFromMemoryAsync()
        {
            string path = Application.streamingAssetsPath + "/" + "prefab";
            //byte by = byte.Parse(path);
            AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
            yield return createRequest;
            AssetBundle bundle = createRequest.assetBundle;
    
            GameObject prefab = bundle.LoadAsset<GameObject>("Cube");
            Instantiate(prefab);
        }
    

    同步:

    private void LoadFromMemory()
        {
            string path = Application.streamingAssetsPath + "/" + "prefab";
            AssetBundle bundle = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
            GameObject prefab = bundle.LoadAsset<GameObject>("Cube");
            Instantiate(prefab);
        }
    

    5.从本地获得网络加载WWW.LoadFromCacheOrDownload
    通过URL进行加载

    IEnumerator LoadFromCacheOrDownLoadExample ()
        {
            while (!Caching.ready)
            {
                yield return null;
            }
            var www = WWW.LoadFromCacheOrDownload("http://192.168.0.250/prefab.unity3d", 5);
            //var www = WWW.LoadFromCacheOrDownload(@"D:\the9git\the9_09\UnityProject\UnityBase04\Assets\StreamingAssets\prefab", 5);
            yield return www;
            if (!string.IsNullOrEmpty(www.error))
            {
                Debug.Log(www.error);
                yield return null;
            }
            AssetBundle myLoadedAB = www.assetBundle;
            GameObject prefab = myLoadedAB.LoadAsset<GameObject>("Cube");
            Instantiate(prefab);
            //var asset = myLoadedAB.mainAsset;
        }
    

    6.通过UnityWebRequest加载AB包

        IEnumerator InstantiateObject()
        {
            //string uri = "file:///" + Application.streamingAssetsPath + "/prefab";
            string uri = "http://192.168.0.250/StreamingAssets/perfab.unity3d";
            using (UnityWebRequest webRequest = UnityWebRequest.GetAssetBundle(uri))
            {
                yield return webRequest.SendWebRequest();
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(webRequest);
                GameObject cube = bundle.LoadAsset<GameObject>("Cube");
                Instantiate(cube);
            }
            string uri2 = "http://192.168.0.250/StreamingAssets/StreamingAssets";
            using (UnityWebRequest webRequest2 = UnityWebRequest.GetAssetBundle(uri2))
            {
                yield return webRequest2.SendWebRequest();
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(webRequest2);
                AssetBundleManifest assetBundleManifes = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
                string[] dps = assetBundleManifes.GetAllDependencies("perfab.unity3d");
                for (int i = 0; i < dps.Length; i++)
                {
                    string uri3 = "http://192.168.0.250/StreamingAssets/" + dps[i];
                    using (UnityWebRequest webRequest3 = UnityWebRequest.GetAssetBundle(uri3))
                    {
                        yield return webRequest3.SendWebRequest();
                        AssetBundle ab = DownloadHandlerAssetBundle.GetContent(webRequest3);
                    }
                }
            }
        }
    

    卸载有两个方面
    1,减少内存使用
    2,有可能导致丢失
    所以什么时候去卸载资源
    AssetBundle.Unload(true)将使全部InstanceID对应的GUID和localID无效,即使有资源被使用着,所有资源将显示为Missing。
    (1,在关切切换、场景切换2,资源没被用的时候 调用)
    AssetBundle.Unload(false)卸载所有没用被使用的资源
    个别资源怎么卸载1,通过 Resources.UnloadUnusedAssets. 2,场景切换的时候
    AssetBundle卸载

    相关文章

      网友评论

          本文标题:Unity-资源打包-AssetBundle

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