0.资源加载方式

  1. 静态资源 Asset下所有资源称为静态资源
  2. Resources资源 Resources目录下,通过实例化得到的资源
  3. AssetBundle资源 又称为增量更新资源

1.什么是AssetBundle包(下面称为AB包)

  一种存放在硬盘上压缩文件组形式,包含序列化文件(Manifest)与资源文件(Resources)。压缩包的压缩算法包括LZMA(流式压缩)与LZ4(块压缩)算法,前者压缩比例更高解压耗时更大。

  PS:www使用后是需要销毁的!!!www.Dispose();

2.AB包打包原则有哪些

  • 引用同意贴图、材质、模型的资源最好一起打包
  • 一起展示的部分最好一起打包,比如一个场景,一个面板等
  • 导出目录一定要存在,不存在导出会失败
  • 加载资源时请务必清空一次缓存区!!重要!重要!

3.AB场景资源打包

  • 打包前把需要的shader放到Edit/ProjectSetting/Graphics 的Always Includes Shaders上,不然加载后会出现shader关联不上的问题

方式1.场景打包方式0 (打成多个资源包)


  • 设置要打包的场景资源

  • Editor中导入如下代码
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;
  4. using System.IO;
  5.  
  6. public class ABSceneAll
  7. {
  8. [MenuItem("Custom Editor/Version1CreateAB")]
  9. static void CreateSceneVersion1()
  10. {
  11. //清空一下缓存
  12. Caching.CleanCache();
  13.  
  14. //路径
  15. string outPath = Application.streamingAssetsPath + "/AssetBundle";
  16. if (!Directory.Exists(outPath))
  17. {
  18. Directory.CreateDirectory(outPath);
  19. }
  20.  
  21. //检测所有的AB包资源创建Manifest文件 这里选择的是不进行任何特殊要求
  22. AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.Android);
  23.  
  24. //存储txt文件
  25. if (manifest != null)
  26. {
  27. string txtPath = Application.streamingAssetsPath + "/AssetBundle" + "/gamehall.txt";
  28. string manifestPath = Application.streamingAssetsPath + "/AssetBundle" + "/AssetBundle.assetbundle";
  29. string temp = "";
  30.  
  31. //得到所有的需要打AB包的资源名
  32. string[] assetBundleNames = manifest.GetAllAssetBundles();
  33.  
  34. //提示信息 & 安全校验
  35. if (assetBundleNames.Length != )
  36. {
  37. EditorUtility.DisplayDialog("错误提示", "这是个安全校验,表示已经出问题了打包的场景过多", "确定");
  38. return;
  39. }
  40.  
  41. for (int i = ; i < assetBundleNames.Length; i++)
  42. {
  43. temp += assetBundleNames[i] + ":" + manifest.GetAssetBundleHash(assetBundleNames[i]).ToString() + "\r\n";
  44. }
  45. temp += "前二十位:" + manifest.GetAssetBundleHash(assetBundleNames[]).ToString().Substring(, ) + manifest.GetAssetBundleHash(assetBundleNames[]).ToString().Substring(, );
  46.  
  47. FileStream fs = new FileStream(txtPath, FileMode.OpenOrCreate, FileAccess.Write);//创建写入文件
  48. StreamWriter sw = new StreamWriter(fs);
  49. sw.WriteLine(temp);//开始写入值
  50. sw.Close();
  51. fs.Close();
  52. }
  53.  
  54. //资源刷新
  55. AssetDatabase.Refresh();
  56. }
  57. }
  • Custom Editor中选择对应选项进行打包(这里打出来的包就包含了Manifest文件,2个不同的AB文件)
  • 读取方式如下代码
  1. /***************************************
  2. Editor: Tason
  3. Version: v1.0
  4. Last Edit Date: 2018-XX-XX
  5. Tel: 328791554@qq.com
  6. Function Doc:
  7.  
  8. ***************************************/
  9.  
  10. using UnityEngine;
  11. using System.Collections;
  12.  
  13. public class MyTest : MonoBehaviour
  14. {
  15. void Awake()
  16. {
  17.  
  18. StartCoroutine(LoadScene());
  19. }
  20.  
  21. private IEnumerator LoadScene()
  22. {
  23. Caching.CleanCache();
  24. //加载多个文件 Manifest + AssetBundle资源
  25. WWW downManifest = WWW.LoadFromCacheOrDownload("file://" + Application.streamingAssetsPath + "/AssetBundle" + "/AssetBundle", );
  26. //加载时间 600 * 0.1s 最长加载60s
  27. for (int i = ; i < ; i++)
  28. {
  29. if (downManifest.isDone)
  30. {
  31. break;
  32. }
  33. if (i % == )
  34. Debug.Log("加载进度:" + downManifest.progress.ToString("#0.00"));
  35. yield return new WaitForSeconds(0.1f);
  36. }
  37. if (downManifest.isDone)
  38. Debug.Log("文件目录加载成功 ----- √");
  39. else
  40. {
  41. Debug.Log("文件目录加载失败 ----- X");
  42. yield break;
  43. }
  44.  
  45. AssetBundleManifest abm = downManifest.assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  46. string[] abResourcesNames = abm.GetAllAssetBundles();
  47. for (int i = ; i < abResourcesNames.Length; ++i)
  48. {
  49. WWW downResource = WWW.LoadFromCacheOrDownload("file://" + Application.streamingAssetsPath + "/AssetBundle" + '/' + abResourcesNames[i], );
  50. for (int n = ; n < ; n++)
  51. {
  52. if (downResource.isDone)
  53. {
  54. break;
  55. }
  56. if (i % == )
  57. Debug.Log("加载进度:" + downManifest.progress.ToString("#0.00"));
  58. yield return new WaitForSeconds(0.1f);
  59. }
  60. if (downResource.isDone)
  61. Debug.Log(string.Format("文件[{0}]加载成功 ----- √", i));
  62. else
  63. {
  64. Debug.Log(string.Format("文件[{0}]加载失败 ----- X", i));
  65. yield break;
  66. }
  67.  
  68. }
  69.  
  70. Application.LoadLevel("S1");
  71.  
  72. yield return null;
  73.  
  74. }
  75. }

方式2.场景打包方式1(打成1个资源包)


  • 设置要打包的场景资源

  • Editor中导入如下代码
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;
  4. using System.IO;
  5.  
  6. public class ABSceneAll
  7. {
  8. [MenuItem("Custom Editor/Version0CreateAB")]
  9. static void CreateSceneVersion0()
  10. {
  11. //清空一下缓存
  12. Caching.CleanCache();
  13.  
  14. //路径
  15. string outPath = Application.streamingAssetsPath + "/AssetBundle";
  16. if (!Directory.Exists(outPath))
  17. {
  18. Directory.CreateDirectory(outPath);
  19. }
  20.  
  21. string TtargetPath = outPath + "/MY01.AB";
  22. string[] Scenes = { "Assets/Scene/S0.unity","Assets/Scene/S1.unity" };
  23.  
  24. //打包场景
  25. BuildPipeline.BuildPlayer(Scenes, TtargetPath, BuildTarget.Android, BuildOptions.BuildAdditionalStreamedScenes);
  26.  
  27. //资源刷新
  28. AssetDatabase.Refresh();
  29. }
  30. }
  • Custom Editor中选择第一个选项进行打包(这里打出来的包就是一个AB文件)
  • 读取方式如下代码
  1. /***************************************
  2. Editor: Tason
  3. Version: v1.0
  4. Last Edit Date: 2018-XX-XX
  5. Tel: 328791554@qq.com
  6. Function Doc:
  7.  
  8. ***************************************/
  9.  
  10. using UnityEngine;
  11. using System.Collections;
  12.  
  13. public class MyTest : MonoBehaviour
  14. {
  15. void Awake()
  16. {
  17.  
  18. StartCoroutine(LoadScene());
  19. }
  20.  
  21. private IEnumerator LoadScene()
  22. {
  23. Caching.CleanCache();
  24. //资源加载 对应单一资源
  25. WWW download = WWW.LoadFromCacheOrDownload("file://" + Application.streamingAssetsPath + "/AssetBundle" + "/MY01.AB", );
  26. yield return download;
  27. Application.LoadLevel("S1");
  28. download.Dispose();
  29.  
  30. yield return null;
  31.  
  32. }
  33. }

AB包卸载


1.减少内存消耗

2.可能导致丢失的情况

AssetBundle.Unload(bool _b); ----- 这里不是静态函数,前面要写获得的AB包对象

True: 强制卸载,不管有没有引用

False:卸载没有用的资源

踩坑


  1. AssetBunlde不区分大小写 所以建议全部用小写
  2. Resources和AssetBundle路径不同,Resources是相对路径,AssetBundle都有
  3. 依赖关系一定要处理好,不然包体会很大
  4. AssetBundle.CreateFromFile不能加载压缩过的AssetBundle,需要用www加载?!
  5. 资源间的关系必须是强关联,不能有资源通过代码里面的“Resources.Load<Type>”“Shader.Find”等弱关联连接,因为它不会被打包进AB包(已测试,非常关键)
  6. 如果你要把资源包放在StreamingAssets目录下进行资源加载,注意三端的路径是不一样的(这就很虚浮!)

    

  1. #if UNITY_EDITOR || UNITY_STANDALONE_WIN
  2. string finalPath = "file://" + Application.dataPath + "/StreamingAssets";
  3. #elif UNITY_ANDROID
  4. string finalPath = "jar:file://" + Application.dataPath + "!/assets";
  5. #elif UNITY_IPHONE
  6. string finalPath = Application.dataPath + "/Raw"
  7. #endif

  

Shader&AB包的关系!


1.首先场景中关联了材质的shader是会被打包到AB包中的(如果没打包进去,就去菜单栏 Edit -----> ProjectSetting ----> Graphics -----> Always Included Shaders 中进行添加)

  EG:后面我又做了个实验,通过AssetBundleBrower检查过一次,发现确实打包进去了,但UITexture的Shader还是存在问题,使用上需要格外小心,最好还是给引用的地方放一份Shader,ε=(´ο`*)))很是无奈啊!!!!

2.但是存在一些问题,比如加载AB的场景可能会存在“关联丢失”的问题,表现出来的方式就像是shader没有被打包,但是当你重新点选同样的shader后又恢复了!这就很坑爹,原因不明

3.那么如何解决这个问题呢,我参考了网上的一个方法,测试成功表示可行,在需要挂在新shader的父物体下面加上如下脚本即可,相当于它帮你记录了关联,然后运行时重新关联了一次!(适用于Mesh UGUI)

4.当然如果你的代码里面存在创建模型这种骚操作,上诉挂载的方式是肯定行不通的,那就需要你自己加一句代码来重新关联咯,如:“m_materials[0].shader = Shader.Find("Custom/CutLineShader");”

  1. /***************************************
  2. Editor: Tason
  3. Last Edit Date: 2018-XX-XX
  4. Tel: 328791554@qq.com
  5. Function Doc:
  6. 在需要自定义的使用自定义shader的物体的最上层父物体上加上这个
  7. 脚本可以保证shader关联不丢失
  8. Version: 0.0.1 测试版
  9. ***************************************/
  10.  
  11. using UnityEngine;
  12. using System.Collections;
  13. using System.Collections.Generic;
  14.  
  15. public class ShaderBD : MonoBehaviour
  16. {
  17. private List<Material> thisMaterial;
  18. private List<string> shaders;
  19.  
  20. void Start()
  21. {
  22. thisMaterial = new List<Material>();
  23. shaders = new List<string>();
  24.  
  25. MeshRenderer[] meshRenderer = GetComponentsInChildren<MeshRenderer>();
  26. int length = meshRenderer.Length;
  27.  
  28. for (int i = ; i < length; i++)
  29. {
  30. int count = meshRenderer[i].materials.Length;
  31. for (int j = ; j < count; j++)
  32. {
  33. Material _mater = meshRenderer[i].materials[j];
  34. thisMaterial.Add(_mater);
  35. shaders.Add(_mater.shader.name);
  36. }
  37. }
  38.  
  39. SkinnedMeshRenderer[] meshSkinRenderer = GetComponentsInChildren<SkinnedMeshRenderer>();
  40. length = meshSkinRenderer.Length;
  41.  
  42. for (int i = ; i < length; i++)
  43. {
  44. int count = meshSkinRenderer[i].materials.Length;
  45. for (int j = ; j < count; j++)
  46. {
  47. Material _mater = meshSkinRenderer[i].materials[j];
  48. thisMaterial.Add(_mater);
  49. shaders.Add(_mater.shader.name);
  50. }
  51. }
  52.  
  53. for (int i = ; i < thisMaterial.Count; i++)
  54. {
  55. thisMaterial[i].shader = Shader.Find(shaders[i]);
  56. }
  57. }
  58. }

总结:如果需要使用AB包进行场景打包,那么NGUI上使用的Shader,需要单独放在整合包(ABLoad的项目)中,如果是UGUI或者Mesh使用Shader,请在父物体上挂载上述脚本进行关联!!!!后续持续关注

对了!下面是AssetBundleBrower(查看打包内容的UnityEditor 工具,直接导入Editor,在Window窗口中就能找到它了!支持5.6以上版本)

链接:https://pan.baidu.com/s/1BN2EofgVXIthKiAIq3JPyg 密码:mg8i

AssetBundle使用心得【资源加载】的更多相关文章

  1. 详谈 Unity3D AssetBundle 资源加载,结合实际项目开发实例

    第一次搞资源更新方面,这里只说更新,加载,AssetBundle资源加载,谈谈自己的理解,以及自己在项目中遇到的那些神坑,现在回想一下,真的是自己跪着过来的,说多了,都是泪. 我这边是安卓AssetB ...

  2. Unity -- AssetBundle(本地资源加载和加载依赖关系)

    1.本地资源加载 1).建立Editor文件夹 2).建立StreamingAssets文件夹和其Windows的子文件夹 将下方第一个脚本放入Editor 里面 脚本一  资源打包AssetBund ...

  3. Unity3D之Mecanim动画系统学习笔记(十):Mecanim动画的资源加载相关

    资源加载是必备的知识点,这里就说说Mecanim动画的资源如何打包及加载. 注意,Unity4.x和Unity5.x的AssetBundle打包策略不一样,本笔记是基于Unity4.x的AssetBu ...

  4. Unity AssetBundle的生成、加载和热更新

    当前使用的是unity2018.2.6版本. 生成AssetBundle 这个版本生成AssetBundle有两种方式,一种是在资源的Inspector面板下边配置AssetBundle名称,然后调用 ...

  5. Unity AssetBundle的几个加载方式

    string path = @"AssetBundles/scene/cubewall.ab"; string cacheDownloadPath = @"file:// ...

  6. 细谈unity资源加载和卸载

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概要 在了解unity的资源管理方式之后,接下来细谈一下Unity的资源是如何从磁盘中加载到运行时的内存中,以及又是如 ...

  7. Direct2D开发:从资源加载位图

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 Direct2D使用Windows图像处理组件 (WIC) 来加载位图.从文件加载位图的方法很简单,而且网上的教 ...

  8. prelaod场景,用来显示资源加载进度

    phaser.js的源码可以到它在github上的托管里去下载,游戏要用到的图片声音等素材资源请点击这里下载.Phaser的使用非常简单,只需要引入它的主文件,然后在页面中指定一个用来放置canvas ...

  9. 【Android开发学习笔记】【高级】【随笔】插件化——资源加载

    前言 上一节我们针对插件最基本的原理进行了一个简单的demo实现,但是由于插件的Context对象被宿主所接管,因此无法加载插件程序的资源.那么如何解决这个问题捏? 有人提出这样的方案:将apk中的资 ...

随机推荐

  1. delphi WebBrowser IPv6

    We discovered one or more bugs in your app when reviewed on iPhone running iOS 11.4 on Wi-Fi connect ...

  2. centos 7设置本地yum资源库

    前言 同样的,是在这两天安装ambari的时候遇到的问题之一,那就是关于centos的本地yum源的制作,当时是一种是制作iso镜像的yum源,还有一种将rpm软件包打成压缩包上传到centos的某一 ...

  3. XSLT 创建CDATA节点

    创建文本结点 (1)直接写入文本: text1 (2)通过<xsl:text>创建文本结点: <xsl:text>text2</xsl:text> (3)通过< ...

  4. Hibernate 再接触 总结

  5. cdnbest架设cdn同一个源用不同的端口访问如何设置

    在站点里的应用防火墙-->高级设置里配置 比如test.com要同时用80和88访问

  6. SQL Server日志文件过大 大日志文件清理方法 不分离数据库

    SQL Server日志文件过大    大日志文件清理方法 ,网上提供了很多分离数据库——〉删除日志文件-〉附加数据库 的方法,此方法风险太大,过程也比较久,有时候也会出现分离不成功的现象.下面的方式 ...

  7. python 网络编程 缓冲和粘包

    tcp:属于长连接,与一个客户端进行连接了以后,其他的客户端要等待,要连接另外一个,必须优雅的断开前面这个客户端的连接. 允许地址重用:在bind IP地址和端口之前加上,# server.setso ...

  8. Springboot学习04-默认错误页面加载机制源码分析

    Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...

  9. 最短路径(SP)问题相关算法与模板

    相关概念: 有向图.无向图:有向图的边是双行道,无向图的边是单行道.在处理无向图时,可以把一条无向边看做方向相反的两条有向边. 圈 cycle / 回路 circuit:在相同顶点上开始并结束且长度大 ...

  10. Pandas plot出图

    1.创建一个Series 这是一个线性的数据,我们随机生成1000个数据,Series 默认的 index 就是从0开始的整数,但是这里我显式赋值以便让大家看的更清楚 >>> imp ...