0.资源加载方式
- 静态资源 Asset下所有资源称为静态资源
- Resources资源 Resources目录下,通过实例化得到的资源
- AssetBundle资源 又称为增量更新资源
1.什么是AssetBundle包(下面称为AB包)
一种存放在硬盘上压缩文件组形式,包含序列化文件(Manifest)与资源文件(Resources)。压缩包的压缩算法包括LZMA(流式压缩)与LZ4(块压缩)算法,前者压缩比例更高解压耗时更大。
PS:www使用后是需要销毁的!!!www.Dispose();
2.AB包打包原则有哪些
- 引用同意贴图、材质、模型的资源最好一起打包
- 一起展示的部分最好一起打包,比如一个场景,一个面板等
- 导出目录一定要存在,不存在导出会失败
- 加载资源时请务必清空一次缓存区!!重要!重要!
3.AB场景资源打包
方式1.场景打包方式0 (打成多个资源包)
- 设置要打包的场景资源
- Editor中导入如下代码
using UnityEngine; using System.Collections; using UnityEditor; using System.IO; public class ABSceneAll { [MenuItem("Custom Editor/Version1CreateAB")] static void CreateSceneVersion1() { //清空一下缓存 Caching.CleanCache(); //路径 string outPath = Application.streamingAssetsPath + "/AssetBundle"; if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } //检测所有的AB包资源创建Manifest文件 这里选择的是不进行任何特殊要求 AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.Android); //存储txt文件 if (manifest != null) { string txtPath = Application.streamingAssetsPath + "/AssetBundle" + "/gamehall.txt"; string manifestPath = Application.streamingAssetsPath + "/AssetBundle" + "/AssetBundle.assetbundle"; string temp = ""; //得到所有的需要打AB包的资源名 string[] assetBundleNames = manifest.GetAllAssetBundles(); //提示信息 & 安全校验 if (assetBundleNames.Length != 2) { EditorUtility.DisplayDialog("错误提示", "这是个安全校验,表示已经出问题了打包的场景过多", "确定"); return; } for (int i = 0; i < assetBundleNames.Length; i++) { temp += assetBundleNames[i] + ":" + manifest.GetAssetBundleHash(assetBundleNames[i]).ToString() + "\r\n"; } temp += "前二十位:" + manifest.GetAssetBundleHash(assetBundleNames[1]).ToString().Substring(0, 10) + manifest.GetAssetBundleHash(assetBundleNames[0]).ToString().Substring(0, 10); FileStream fs = new FileStream(txtPath, FileMode.OpenOrCreate, FileAccess.Write);//创建写入文件 StreamWriter sw = new StreamWriter(fs); sw.WriteLine(temp);//开始写入值 sw.Close(); fs.Close(); } //资源刷新 AssetDatabase.Refresh(); } }
- Custom Editor中选择对应选项进行打包(这里打出来的包就包含了Manifest文件,2个不同的AB文件)
- 读取方式如下代码
/*************************************** Editor: Tason Version: v1.0 Last Edit Date: 2018-XX-XX Tel: [email protected] Function Doc: ***************************************/ using UnityEngine; using System.Collections; public class MyTest : MonoBehaviour { void Awake() { StartCoroutine(LoadScene()); } private IEnumerator LoadScene() { Caching.CleanCache(); //加载多个文件 Manifest + AssetBundle资源 WWW downManifest = WWW.LoadFromCacheOrDownload("file://" + Application.streamingAssetsPath + "/AssetBundle" + "/AssetBundle", 1); //加载时间 600 * 0.1s 最长加载60s for (int i = 0; i < 600; i++) { if (downManifest.isDone) { break; } if (i % 3 == 0) Debug.Log("加载进度:" + downManifest.progress.ToString("#0.00")); yield return new WaitForSeconds(0.1f); } if (downManifest.isDone) Debug.Log("文件目录加载成功 ----- √"); else { Debug.Log("文件目录加载失败 ----- X"); yield break; } AssetBundleManifest abm = downManifest.assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); string[] abResourcesNames = abm.GetAllAssetBundles(); for (int i = 0; i < abResourcesNames.Length; ++i) { WWW downResource = WWW.LoadFromCacheOrDownload("file://" + Application.streamingAssetsPath + "/AssetBundle" + '/' + abResourcesNames[i], 1); for (int n = 0; n < 600; n++) { if (downResource.isDone) { break; } if (i % 3 == 0) Debug.Log("加载进度:" + downManifest.progress.ToString("#0.00")); yield return new WaitForSeconds(0.1f); } if (downResource.isDone) Debug.Log(string.Format("文件[{0}]加载成功 ----- √", i)); else { Debug.Log(string.Format("文件[{0}]加载失败 ----- X", i)); yield break; } } Application.LoadLevel("S1"); yield return null; } }
方式2.场景打包方式1(打成1个资源包)
- 设置要打包的场景资源
- Editor中导入如下代码
using UnityEngine; using System.Collections; using UnityEditor; using System.IO; public class ABSceneAll { [MenuItem("Custom Editor/Version0CreateAB")] static void CreateSceneVersion0() { //清空一下缓存 Caching.CleanCache(); //路径 string outPath = Application.streamingAssetsPath + "/AssetBundle"; if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } string TtargetPath = outPath + "/MY01.AB"; string[] Scenes = { "Assets/Scene/S0.unity","Assets/Scene/S1.unity" }; //打包场景 BuildPipeline.BuildPlayer(Scenes, TtargetPath, BuildTarget.Android, BuildOptions.BuildAdditionalStreamedScenes); //资源刷新 AssetDatabase.Refresh(); } }
- Custom Editor中选择第一个选项进行打包(这里打出来的包就是一个AB文件)
- 读取方式如下代码
/*************************************** Editor: Tason Version: v1.0 Last Edit Date: 2018-XX-XX Tel: [email protected] Function Doc: ***************************************/ using UnityEngine; using System.Collections; public class MyTest : MonoBehaviour { void Awake() { StartCoroutine(LoadScene()); } private IEnumerator LoadScene() { Caching.CleanCache(); //资源加载 对应单一资源 WWW download = WWW.LoadFromCacheOrDownload("file://" + Application.streamingAssetsPath + "/AssetBundle" + "/MY01.AB", 1); yield return download; Application.LoadLevel("S1"); download.Dispose(); yield return null; } }
AB包卸载
1.减少内存消耗
2.可能导致丢失的情况
AssetBundle.Unload(bool _b); ----- 这里不是静态函数,前面要写获得的AB包对象
True: 强制卸载,不管有没有引用
False:卸载没有用的资源
踩坑
- AssetBunlde不区分大小写 所以建议全部用小写
- Resources和AssetBundle路径不同,Resources是相对路径,AssetBundle都有
- 依赖关系一定要处理好,不然包体会很大
- AssetBundle.CreateFromFile不能加载压缩过的AssetBundle,需要用www加载?!