当前位置:   article > 正文

AssetBundle5.0 打包,下载到本地,加载_本地加载功能包下载

本地加载功能包下载

打包:

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. using System;
  6. using UnityEditor;
  7. /// <summary>
  8. /// 创建AssetBundle
  9. /// </summary>
  10. public class CreateAssetBundle : MonoBehaviour
  11. {
  12. //生成到的目录
  13. public static string Build2Path = Application.dataPath + "/BuildABs";
  14. public static BuildTarget target = BuildTarget.iOS;
  15. [MenuItem("CYH_Tools/AB_Packager/Build_2_IPhone")]
  16. public static void BuildiPhoneResource()
  17. {
  18. target = BuildTarget.iOS;
  19. BuildAssetResource(target);
  20. }
  21. [MenuItem("CYH_Tools/AB_Packager/Build_2_Android")]
  22. public static void BuildAndroidResource()
  23. {
  24. target = BuildTarget.Android;
  25. BuildAssetResource(target);
  26. }
  27. [MenuItem("CYH_Tools/AB_Packager/Build_2_Windows")]
  28. public static void BuildWindowsResource()
  29. {
  30. target = BuildTarget.StandaloneWindows;
  31. BuildAssetResource(target);
  32. }
  33. private static void BuildAssetResource(BuildTarget target)
  34. {
  35. //文件已经存在就删除
  36. if (Directory.Exists(Build2Path))
  37. {
  38. Directory.Delete(Build2Path, true);
  39. }
  40. //文件不存在就创建
  41. if (!Directory.Exists(Build2Path))
  42. {
  43. Directory.CreateDirectory(Build2Path);
  44. }
  45. //打包
  46. BuildPipeline.BuildAssetBundles(Build2Path, BuildAssetBundleOptions.None, target);
  47. }
  48. }

下载到本地和加载:

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. using System;
  6. public delegate void dlg_OnAssetBundleDownLoadOver();
  7. /// <summary>
  8. /// 加载AssetBundle
  9. /// </summary>
  10. public class LoadAssetBundle : SingleFramework<LoadAssetBundle>
  11. {
  12. public override void Init()
  13. {
  14. }
  15. //不同平台下StreamingAssets的路径设置
  16. public static readonly string PathURL =
  17. #if UNITY_ANDROID
  18. "jar:file://" + Application.dataPath + "!/assets/";
  19. #elif UNITY_IPHONE
  20. Application.dataPath + "/Raw/";
  21. #elif UNITY_STANDALONE_WIN || UNITY_EDITOR
  22. "file://" + Application.dataPath + "/StreamingAssets/";
  23. #else
  24. string.Empty;
  25. #endif
  26. //5.0版本打包时候选中需要打包的东西然后设置右下角名称,同个/设置多集目录,后面的框标记后缀(后缀不重要)
  27. //打包时候的目标文件夹,假设目标文件夹名称为"WJJ",那么会生成"WJJ"和"WJJ.manifest"两个文件
  28. //其中WJJ.manifest文件没有用,只是用来看的,WJJ是一个assetbundle包,里面包含了整个文件夹的依赖信息
  29. //可以先加载这个东西,然后获取到依赖关系后逐步加载
  30. //递一般归加载并保存到Application.persistentDataPath
  31. //注意用GetDirectDependencies递归,不要用GetAllDependencies,因为已经包含孙子儿子又会加载孙子,重复加载了
  32. //简单用法直接获取不要用GetAllDependencies,然后倒序加载
  33. /// <summary>
  34. /// 下载资源到本地包括它的依赖项
  35. /// </summary>
  36. /// <param name="AssetsHost">根目录地址</param>
  37. /// <param name="RootAssetsName"></param>
  38. /// <param name="AssetName"></param>
  39. /// <param name="savePath"></param>
  40. public void DownLoadAssets2LocalWithDependencies(string AssetsHost, string RootAssetsName, string AssetName, string savePath, dlg_OnAssetBundleDownLoadOver OnDownloadOver = null)
  41. {
  42. StartCoroutine(DownLoadAssetsWithDependencies2Local(AssetsHost, RootAssetsName, AssetName, savePath, OnDownloadOver));
  43. }
  44. /// <summary>
  45. /// //从服务器下载到本地
  46. /// </summary>
  47. /// <param name="AssetsHost">服务器路径</param>
  48. /// <param name="RootAssetsName">总依赖文件目录路径</param>
  49. /// <param name="AssetName">请求资源名称</param>
  50. /// <param name="saveLocalPath">保存到本地路径,一般存在Application.persistentDataPath</param>
  51. /// <returns></returns>
  52. IEnumerator DownLoadAssetsWithDependencies2Local(string AssetsHost, string RootAssetsName, string AssetName, string saveLocalPath, dlg_OnAssetBundleDownLoadOver OnDownloadOver = null)
  53. {
  54. WWW ServerManifestWWW = null; //用于存储依赖关系的 AssetBundle
  55. AssetBundle LocalManifestAssetBundle = null; //用于存储依赖关系的 AssetBundle
  56. AssetBundleManifest assetBundleManifestServer = null; //服务器 总的依赖关系
  57. AssetBundleManifest assetBundleManifestLocal = null; //本地 总的依赖关系
  58. if (RootAssetsName != "") //总依赖项为空的时候去加载总依赖项
  59. {
  60. ServerManifestWWW = new WWW(AssetsHost + "/" + RootAssetsName);
  61. Debug.Log("___当前请求总依赖文件~\n");
  62. yield return ServerManifestWWW;
  63. if (ServerManifestWWW.isDone)
  64. {
  65. //加载总的配置文件
  66. assetBundleManifestServer = ServerManifestWWW.assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  67. Debug.Log("___当前请求总依赖文件~\n");
  68. }
  69. else
  70. {
  71. throw new Exception("总依赖文件下载失败~~~\n");
  72. }
  73. }
  74. //获取需要加载物体的所有依赖项
  75. string[] AllDependencies = new string[0];
  76. if (assetBundleManifestServer != null)
  77. {
  78. //根据名称获取依赖项
  79. AllDependencies = assetBundleManifestServer.GetAllDependencies(AssetName);
  80. }
  81. //下载队列 并获取每个资源的Hash值
  82. Dictionary<string, Hash128> dicDownloadInfos = new Dictionary<string, Hash128>();
  83. for (int i = AllDependencies.Length - 1; i >= 0; i--)
  84. {
  85. dicDownloadInfos.Add(AllDependencies[i], assetBundleManifestServer.GetAssetBundleHash(AllDependencies[i]));
  86. }
  87. dicDownloadInfos.Add(AssetName, assetBundleManifestServer.GetAssetBundleHash(AssetName));
  88. if (assetBundleManifestServer != null) //依赖文件不为空的话下载依赖文件
  89. {
  90. Debug.Log("Hash:"+assetBundleManifestServer.GetHashCode());
  91. dicDownloadInfos.Add(RootAssetsName, new Hash128(0, 0, 0, 0));
  92. }
  93. //卸载掉,无法同时加载多个配置文件
  94. ServerManifestWWW.assetBundle.Unload(true);
  95. if (File.Exists(saveLocalPath + "/" + RootAssetsName))
  96. {
  97. LocalManifestAssetBundle = AssetBundle.LoadFromFile(saveLocalPath + "/" + RootAssetsName);
  98. assetBundleManifestLocal = LocalManifestAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  99. }
  100. foreach (var item in dicDownloadInfos)
  101. {
  102. if (!CheckLocalFileNeedUpdate(item.Key, item.Value, RootAssetsName, saveLocalPath, assetBundleManifestLocal))
  103. {
  104. Debug.Log("无需下载:" + item.Key);
  105. continue;
  106. }
  107. else
  108. {
  109. DeleteFile(saveLocalPath + "/" + item.Key);
  110. }
  111. //直接加载所有的依赖项就好了
  112. WWW wwwAsset = new WWW(AssetsHost + "/" + item.Key);
  113. //获取加载进度
  114. while (!wwwAsset.isDone)
  115. {
  116. Debug.Log(string.Format("下载 {0} : {1:N1}%", item.Key, (wwwAsset.progress * 100)));
  117. yield return new WaitForSeconds(0.2f);
  118. }
  119. //保存到本地
  120. SaveAsset2LocalFile(saveLocalPath, item.Key, wwwAsset.bytes, wwwAsset.bytes.Length);
  121. }
  122. if (LocalManifestAssetBundle != null)
  123. {
  124. LocalManifestAssetBundle.Unload(true);
  125. }
  126. if (OnDownloadOver != null)
  127. {
  128. OnDownloadOver();
  129. }
  130. }
  131. /// <summary>
  132. /// 检测本地文件是否存在已经是否是最新
  133. /// </summary>
  134. /// <param name="AssetName"></param>
  135. /// <param name="RootAssetsName"></param>
  136. /// <param name="localPath"></param>
  137. /// <param name="serverAssetManifestfest"></param>
  138. /// <param name="CheckCount"></param>
  139. /// <returns></returns>
  140. bool CheckLocalFileNeedUpdate(string AssetName, Hash128 hash128Server, string RootAssetsName, string localPath, AssetBundleManifest assetBundleManifestLocal)
  141. {
  142. Hash128 hash128Local;
  143. bool isNeedUpdate = false;
  144. if (!File.Exists(localPath + "/" + AssetName))
  145. {
  146. return true; //本地不存在,则一定更新
  147. }
  148. if (!File.Exists(localPath + "/" + RootAssetsName)) //当本地依赖信息不存在时,更新
  149. {
  150. isNeedUpdate = true;
  151. }
  152. else //总的依赖信息存在切文件已存在 对比本地和服务器两个文件的Hash值
  153. {
  154. if (hash128Server == new Hash128(0, 0, 0, 0))
  155. {
  156. return true; //保证每次都下载总依赖文件
  157. }
  158. hash128Local = assetBundleManifestLocal.GetAssetBundleHash(AssetName);
  159. //对比本地与服务器上的AssetBundleHash 版本不一致就下载
  160. if (hash128Local != hash128Server)
  161. {
  162. isNeedUpdate = true;
  163. }
  164. }
  165. return isNeedUpdate;
  166. }
  167. /// <summary>
  168. /// 非递归式加载指定AB,并加载依赖项,并返回目标GameObject
  169. /// </summary>
  170. /// <param name="RootAssetsName"></param>
  171. /// <param name="AssetName"></param>
  172. /// <param name="LocalPath"></param>
  173. public GameObject GetLoadAssetFromLocalFile(string RootAssetsName, string AssetName, string PrefabName, string LocalPath)
  174. {
  175. AssetBundle assetBundle = AssetBundle.LoadFromFile(LocalPath + "/" + RootAssetsName);
  176. AssetBundleManifest assetBundleManifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  177. string[] AllDependencies = assetBundleManifest.GetAllDependencies(AssetName);
  178. for (int i = AllDependencies.Length - 1; i >= 0; i--)
  179. {
  180. AssetBundle assetBundleDependencies = AssetBundle.LoadFromFile(LocalPath + "/" + AllDependencies[i]);
  181. assetBundleDependencies.LoadAllAssets();
  182. }
  183. AssetBundle assetTarget = AssetBundle.LoadFromFile(LocalPath + "/" + AssetName);
  184. return assetTarget.LoadAsset<GameObject>(PrefabName);
  185. }
  186. /// <summary>
  187. /// 递归加载本地所有依赖项
  188. /// </summary>
  189. /// <param name="RootAssetsName"></param>
  190. /// <param name="AssetName"></param>
  191. /// <param name="LocalPath"></param>
  192. AssetBundleManifest assetBundleManifestLocalLoad; //递归加载时候用
  193. public void RecursionLoadAssetFromLocalFile(string RootAssetsName, string AssetName, string LocalPath, int RecursionCounter)
  194. {
  195. if (RecursionCounter++ == 0)
  196. {
  197. //加载本地Manifest获取依赖项
  198. assetBundleManifestLocalLoad = AssetBundle.LoadFromFile(LocalPath + "/" + RootAssetsName).LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  199. }
  200. //当前AssetName所有依赖项
  201. string[] AllDependencies = assetBundleManifestLocalLoad.GetDirectDependencies(AssetName);
  202. for (int i = 0; i < AllDependencies.Length; i++)
  203. {
  204. RecursionLoadAssetFromLocalFile(RootAssetsName, AllDependencies[i], LocalPath, RecursionCounter);
  205. }
  206. AssetBundle assetBundle = AssetBundle.LoadFromFile(LocalPath + "/" + AssetName);
  207. assetBundle.LoadAllAssets();
  208. }
  209. /// <summary>
  210. /// 将文件模型创建到本地
  211. /// </summary>
  212. /// <param name="path"></param>
  213. /// <param name="name"></param>
  214. /// <param name="info"></param>
  215. /// <param name="length"></param>
  216. void SaveAsset2LocalFile(string path, string name, byte[] info, int length)
  217. {
  218. Stream sw = null;
  219. FileInfo fileInfo = new FileInfo(path + "/" + name);
  220. if (fileInfo.Exists)
  221. {
  222. fileInfo.Delete();
  223. }
  224. //如果此文件不存在则创建
  225. sw = fileInfo.Create();
  226. //写入
  227. sw.Write(info, 0, length);
  228. sw.Flush();
  229. //关闭流
  230. sw.Close();
  231. //销毁流
  232. sw.Dispose();
  233. Debug.Log(name + "成功保存到本地~");
  234. }
  235. /// <summary>
  236. /// 删除文件
  237. /// </summary>
  238. /// <param name="path"></param>
  239. void DeleteFile(string path)
  240. {
  241. File.Delete(path);
  242. }
  243. }<strong>
  244. </strong>

测试代码:

  1. // Use this for initialization
  2. void Start()
  3. {
  4. //5.0版本打包时候选中需要打包的东西然后设置右下角名称,同个/设置多集目录,后面的框标记后缀(后缀不重要)
  5. //打包时候的目标文件夹,假设目标文件夹名称为"WJJ",那么会生成"WJJ"和"WJJ.manifest"两个文件
  6. //其中WJJ.manifest文件没有用,只是用来看的,WJJ是一个assetbundle包,里面包含了整个文件夹的依赖信息
  7. //可以先加载这个东西,然后获取到依赖关系后逐步加载
  8. string savePath = Application.persistentDataPath;
  9. ShowTip.Instance.ShowMessage(savePath);
  10. try
  11. {
  12. LoadAssetBundle.Instance.DownLoadAssets2LocalWithDependencies("http://127.0.0.1/BuildABs", "BuildABs", "cube", savePath, () =>
  13. {
  14. GameObject obj = LoadAssetBundle.Instance.GetLoadAssetFromLocalFile("BuildABs", "cube", "Cube", Application.persistentDataPath);
  15. GameObject.Instantiate(obj);
  16. ShowTip.Instance.ShowMessage(obj.name);
  17. //obj.GetComponent<Renderer>().sharedMaterial.shader = Shader.Find(obj.GetComponent<Renderer>().sharedMaterial.shader.name);
  18. });
  19. }
  20. catch (Exception ex)
  21. {
  22. Debug.Log(ex.Message);
  23. }
  24. }




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/82278
推荐阅读
相关标签
  

闽ICP备14008679号