首先将资源打包 建一个工程 创建一个蓝色的cube 做成prefab 设置包名 结束 ab包名必须全小写 // 资源包 打包类 不同平台使用各自生成的.ab资源包 不同平台之间不通用 // 不同版本的unity 生成的AB文件或许是不通用的 建议使用相同版本打包并且发布 public class BuildBundle :MonoBehaviour {
[MenuItem("BuildAssetBundle/BuildForWindows")] static void BuildForWindows() { BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); } [MenuItem("BuildAssetBundle/BuildForIOS")] static void BuildForIOS() { BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, BuildAssetBundleOptions.None, BuildTarget.iOS); } [MenuItem("BuildAssetBundle/BuildForAndroid")] static void BuildForAndroid() { BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, BuildAssetBundleOptions.None, BuildTarget.Android); }}
生成菜单之后点击BuildForWindows 然后在将streamingAssetsPath路径下的文件拷贝到persistentDataPath 代码:using UnityEngine; using System.Collections; using System.IO; using System.Collections.Generic;
private void Start() { FileInfo[] files;// 文件数组 List<string> paths = new List<string>();// 路径集合(文件名) if (Directory.Exists(Application.streamingAssetsPath)) { DirectoryInfo d = new DirectoryInfo(Application.streamingAssetsPath);//文件夹 // 获取文件夹内所有文件信息放在文件数组中 files = d.GetFiles("*", SearchOption.AllDirectories); // 遍历文件数组取得所有文件放在路径集合中 for (int i = 0; i < files.Length; i++) { // 过滤meta文件 if (files[i].Name.EndsWith(".meta")) { continue; } Debug.Log(files[i].Name); paths.Add(files[i].Name); } LoadByPath(paths); Debug.Log(paths.Count); } } // 按照路径加载 private void LoadByPath(List<string> paths) { StartCoroutine(CopyFileData(paths)); } IEnumerator CopyFileData(List<string> paths) { for (int i = 0; i < paths.Count; i++) { // 路径 string streamPath = Path.Combine(Application.streamingAssetsPath, paths[i]); if (!streamPath.Contains("file://")) { streamPath = "file://" + streamPath; } WWW www = new WWW(streamPath); yield return www; // 路径 string writePath = Path.Combine(Application.persistentDataPath, paths[i]); // 调用写入persistentDataPath路径下的方法 WriteByPath(www.bytes, writePath); } } private void WriteByPath(byte[] bytes, string writePath) { if (!File.Exists(writePath)) { FileStream stream = new FileStream(writePath, FileMode.Create); stream.Write(bytes, 0, bytes.Length); stream.Flush();// 释放所有相关资源 stream.Close();// 关闭数据流 } } ok 已经将相关资源写入persistentDataPath 接下来让我们造一个蓝色的cube吧 上代码:using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; public class Inst : MonoBehaviour {
string win_persistentDataPath; private void Awake() { Caching.CleanCache();// 清除 LoadFromCacheOrDownload 产生的缓存 // 这里要是三条/ win_persistentDataPath = string.Format("{0}{1}{2}", "file:///", Application.persistentDataPath, "/"); Debug.Log(win_persistentDataPath); } // 加载多个资源包(资源包之间有相互的依赖)根据清单文件来加载 // 注意流程:首先加载资源清单ab包 (.manifest) 加载依赖资源包 最后是资源包 List<string> _AbStr = new List<string>();// 资源包包名集合 List<string> _DependenciesStr = new List<string>();// 依赖项包名集合 // 所有的资源包 Dictionary<string, AssetBundle> _allAbsDic = new Dictionary<string, AssetBundle>(); AssetBundle _dep_ab;// 临时的依赖包 bool _isFull = false;// 依赖项加载完成 // 加载清单 参数路径是总的资源包名 private IEnumerator LoadAbManiFest(string path) { // 参数1路径 参数2 版本号 WWW bundle = WWW.LoadFromCacheOrDownload(path, 0); yield return bundle; // 1.首先下载资源清单Ab包 AssetBundle _manifest_ab = bundle.assetBundle; // 2.获取清单文件 ("AssetBundleManifest")固定写法 AssetBundleManifest amList = (AssetBundleManifest)_manifest_ab.LoadAsset("AssetBundleManifest"); // 3.获取清单后 释放数据 amList是实例清单对象 Unload(false)对清单对象无影响 _manifest_ab.Unload(false); // 4.获取清单中的资源包列表(注意:一个资源包中可以含有多个资源) 并将资源包名存入集合 _AbStr.Clear(); for (int i = 0; i < amList.GetAllAssetBundles().Length; i++) { // 把所有资源包存入集合中 _AbStr.Add(amList.GetAllAssetBundles()[i]); // 获取所有包的依赖项(资源包) 根据具体包名获取对应依赖项 ToList 需要引入Linq命名空间 _DependenciesStr = amList.GetAllDependencies(amList.GetAllAssetBundles()[i]).ToList(); if (_DependenciesStr.Count > 0) { // 包含依赖项 for (int j = 0; j < _DependenciesStr.Count; j++) { if (_allAbsDic.ContainsKey(_DependenciesStr[j])) { continue; } // 加载资源依赖项资源包 string Depend_path = string.Format("{0}{1}", win_persistentDataPath, _DependenciesStr[j]); Debug.Log(Depend_path); // 加载(下载)依赖项资源包 WWW dep_bundle = WWW.LoadFromCacheOrDownload(Depend_path, 0); yield return dep_bundle; _dep_ab = dep_bundle.assetBundle; if (_dep_ab != null) { // 将资源包对象放入字典 键:资源包名 值:具体资源包的对象 _allAbsDic.Add(_DependenciesStr[j], _dep_ab); } } } } _isFull = true; } // 加载所有剩余的独立的非依赖的资源包 AssetBundle _ab; IEnumerator LoadSurplusAbs() { // 依赖资源未加载完成 while (!_isFull) { yield return new WaitForSeconds(0.1f); } for (int i = 0; i < _AbStr.Count; i++) { if (_allAbsDic.ContainsKey(_AbStr[i])) { continue; } string ab_path = string.Format("{0}{1}", win_persistentDataPath, _AbStr[i]); WWW www = WWW.LoadFromCacheOrDownload(ab_path, 0); yield return www; _ab = www.assetBundle; if (_ab != null) { // key :包名 value:包对象 _allAbsDic.Add(_AbStr[i], _ab); } } //不要释放资源包 无论是true或false 否则字典中的数据会丢失 Debug.Log("所有资源包均已加载完毕"); } // 测试加载文件(需要提取的包名和资源要提前整理清晰,例如:ui_ab(包),chatUI 具体的ui预制体) string getAbName = "m_prefabs";// 自定义的预制体包名 string gameobjName = "Cube";//预制体名 Dictionary<string, GameObject> prefabsDic = new Dictionary<string, GameObject>(); GameObject _tempObj; void CreatBlueBox() { if (_allAbsDic.ContainsKey(getAbName)) { prefabsDic.Clear(); for (int i = 0; i < _allAbsDic[getAbName].LoadAllAssets().Length; i++) { _tempObj = _allAbsDic[getAbName].LoadAllAssets()[i] as GameObject; prefabsDic.Add(_tempObj.name, _tempObj); } if (prefabsDic.ContainsKey(gameobjName)) { Instantiate(prefabsDic[gameobjName]); } } } private void OnGUI() { if (GUILayout.Button("加载多个资源包,包括依赖资源,目标资源")) { Debug.Log(win_persistentDataPath + "StreamingAssets"); StartCoroutine(LoadAbManiFest(win_persistentDataPath + "StreamingAssets")); StartCoroutine(LoadSurplusAbs()); } if (GUILayout.Button("创建蓝盒子")) { CreatBlueBox(); } }}
“` ok 把代码挂起来开始运行 先点击加载资源包 之后在点击创建蓝盒子 一个蓝盒子出来了吧 嘻嘻嘻嘻嘻….