当前位置:   article > 正文

Unity3D AssetBundle打包与加载_unity packassettemp

unity packassettemp

Unity3D AssetBundle打包与加载

转载:Unity AssetBundle 从入门到掌握(适合初学者)

           简单AssetBundle打包与加载问题总结

           Unity3d的AssetBundle打包——AssetBundle Browser(简单实现资源复用)

一、什么是AssetBundle?

官网给出的解释:

1、AssetBundle 是一个存档文件,包含可在运行时由 Unity 加载特定于平台的非代码资源(比如模型、纹理、预制件、音频剪辑甚至整个场景)。

2、AssetBundle 可以表示彼此之间的依赖关系。例如,一个 AssetBundle 中的材质可以引用另一个 AssetBundle 中的纹理。为了提高通过网络传输的效率,可以根据用例要求(LZMA 和 LZ4)选用内置算法选择来压缩 AssetBundle。

3、AssetBundle 可用于可下载内容(DLC),减小初始安装大小,加载针对最终用户平台优化的资源,以及减轻运行时内存压力

通俗的讲,就是把资源压缩起来,在游戏运行的过程中动态的加载、下载以及卸载掉资源,这样也缩小了安装包的大小,减轻了内存的压力。

二、AssetBundle 中有什么?

“AssetBundle”可以指两种不同但相关的东西。

1、首先是磁盘上的实际文件。这称为 AssetBundle 存档。AssetBundle 存档是一个容器,就像文件夹一样,可以在其中包含其他文件。这些附加的文件包含两种类型:

(1)一个序列化文件(Serialized File ):其中包含分解为各个对象并写入此单个文件的资源。

(2)资源文件(Resource Files):这是为某些资源(纹理和音频)单独存储的二进制数据块,允许 Unity 高效地在另一个线程上从磁盘加载它们。

2、“AssetBundle”也可以指代通过代码进行交互以便从特定 AssetBundle 存档加载资源的实际 AssetBundle 对象。该对象包含您添加到此存档文件的资源的所有文件路径的映射。

也就是说,我们可以用代码从一个特定的压缩包中加载出一个对象,这个对象包含我们一开始添加到该压缩包中的所有内容。

三、设置要打包资源的AssetBundle属性

1、我们先新建一个Cube,给它挂载一个检测脚本,把它拖到Project资源列表下形成预制体(如下图)。

/

2、在该预制体面板下,可以看到有AssetBundle的标签,单击会看到相应的标签,没有的话我们可以点击“New”新建一个。Remove UnUsed name 是移除没有使用的属性名。

标签名的命名规则:全为小写字母,加不加后缀都可;

有三种写法:

(1)cube

(2)cube.unity3d

(3)cube.assetbundle

3、测试的代码Cube如下:

  1. using UnityEngine;
  2. public class Cube : MonoBehaviour {
  3. private bool mouseIn;
  4. private GUIStyle style = new GUIStyle();
  5. private void OnMouseEnter()
  6. {
  7. mouseIn = true;
  8. }
  9. private void OnMouseExit()
  10. {
  11. mouseIn = false;
  12. }
  13. private void OnGUI()
  14. {
  15. if (mouseIn)
  16. {
  17. style.fontSize = 30;
  18. style.normal.textColor = Color.red;
  19. style.alignment = TextAnchor.MiddleCenter;
  20. GUI.Label(new Rect(Camera.main.WorldToScreenPoint(transform.position).x, Camera.main.WorldToScreenPoint(transform.position).y + 50, 100, 50), "This is a Cube!", style);
  21. }
  22. }
  23. }

四、打包AssetBundle

接下来,试着将上面的Cube预制体打包。打包的代码如下:(该脚本要放在Project下的Editor文件夹中)

  1. #if UNITY_EDITOR
  2. using UnityEditor;
  3. #endif
  4. using UnityEngine;
  5. public class BuildEditor : MonoBehaviour
  6. {
  7. /// <summary>
  8. /// 编辑器扩展,该脚本需要放到Editor文件夹下
  9. /// 需要注意的:放在Editor文件夹下的脚本在打包时不会被发布出去(也就是不会被打包出去)
  10. /// </summary>
  11. [MenuItem("Bulid/Bulid AssetBundles")]
  12. //unity的编辑器扩展,使用的时候需要引入命名空间using UnityEditor
  13. //当点击Bulid AssetBundles的时候,会执行下面的方法
  14. static void BulidAllAssetBundles()
  15. {
  16. //打包AssetBundles的方法
  17. //unity5里面的BuildPipeline方法
  18. //测试本地加载 方法 StreamingAssets的路径下
  19. //宏定义 选择发布平台:这样写可以在发布不同平台的时候不需要修改代码
  20. #if UNITY_ANDROID//安卓平台
  21. BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath,
  22. BuildAssetBundleOptions.UncompressedAssetBundle,
  23. BuildTarget.Android);
  24. #elif UNITY_IPHONE//iOS平台
  25. BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath,
  26. BuildAssetBundleOptions.UncompressedAssetBundle,
  27. BuildTarget.IOS);
  28. #elif UNITY_STANDALONE_WIN || UNITY_EDITOR
  29. BuildPipeline.BuildAssetBundles(
  30. Application.streamingAssetsPath,//打包后文件的存放路径
  31. BuildAssetBundleOptions.UncompressedAssetBundle,//是否压缩
  32. BuildTarget.StandaloneWindows);//标准window平台,AssetBundles资源在不同平台下不共享
  33. #endif
  34. }
  35. }

完成后,Unity的导航栏会出现AssetBundleTools。

先建一个StreamingAssets文件夹,再点击Bulid AssetBundles,就可以打包了。打包完后,有如下文件(后面再打包,不会再生成后面两个StreamingAssets文件):

并且可以把Cube跟预制体Cube删掉,不过要记得标签名跟预制体名,后面加载的时候需要用到。

五、AssetBundle资源的加载

AssetBundle加载方式:

  1. AssetBundle.LoadFromFile 从本地加载
  2. AssetBundle.LoadFromMemory 从内存加载
  3. WWW.LoadFromCacheOrDownload 下载后放在缓存中备用(该方法逐渐被弃用)
  4. UnityWebRequest 从服务器下载

从AssetBundle中加载资源:

  1. AssetBundle.LoadAsset(assetName)
  2. AssetBundle.LoadAllAssets() 加载AB包中所有的对象,不包含依赖的包
  3. AssetBundle.LoadAssetAsync() 异步加载,加载较大资源的时候
  4. AssetBundle.LoadAllAssetsAsync() 异步加载全部资源
  5. AssetBundle.LoadAssetWithSubAssets 加载资源及其子资源

以下这张表是当使用不同的压缩方式和不同的加载方法时,内存和性能的开销情况比较:

​​​​​​​

 

打包完,我们试着加载一下刚打包过的资源。

新建一个C#脚本,命名为Load,进行代码的编写,编写完,把它挂在场景的一个物体上,填好对应的名称即可。

  1. using System.Collections;
  2. using UnityEngine;
  3. public class Load : MonoBehaviour {
  4. //这个路径是打包的路径,(简单的说就是你的AssetBundle包的路径)
  5. private string pathUrl;
  6. [Header("标签名:")]
  7. public string assetBundle;
  8. [Header("预制体名:")]
  9. public string prefabName;
  10. private void Start()
  11. {
  12. //pathUrl = “file://” + Application.dataPath + “/StreamingAssets/”;
  13. pathUrl =
  14. #if UNITY_ANDROID
  15. "jar:file://"+Application.dataPath+"!/assets/";
  16. #elif UNITY_IPHONE
  17. Application.dataPath+"/Raw/";
  18. #elif UNITY_STANDALONE_WIN||UNITY_EDITOR
  19. "file://" + Application.dataPath + "/StreamingAssets/";
  20. #endif
  21. }
  22. void OnGUI()
  23. {
  24. if (GUI.Button(new Rect (100,100,100,50), "LoadAsset"))
  25. {
  26. StartCoroutine(LoadAsset());
  27. }
  28. }
  29. /// <summary>
  30. /// 加载assetBundle文件
  31. /// </summary>
  32. /// <returns></returns>
  33. private IEnumerator LoadAsset()
  34. {
  35. string mUrl = pathUrl + assetBundle;
  36. Debug.Log(mUrl);
  37. WWW www = new WWW(mUrl);
  38. Debug.Log(www.url);
  39. //等待www加载完成
  40. yield return www;
  41. if (!string.IsNullOrEmpty(www.error))
  42. {
  43. Debug.LogError(www.error);
  44. }
  45. else
  46. {
  47. //加载资源
  48. Object obj = www.assetBundle.LoadAsset(prefabName);
  49. //返回实例化对象
  50. yield return Instantiate(obj);
  51. //false:卸载用过的,true卸载全部
  52. www.assetBundle.Unload(false);
  53. }
  54. //非托管资源:GC处理不了的,一些流文件都会继承IDisposable接口
  55. www.Dispose();//释放资源
  56. }
  57. }

最终效果:

六、AssetBundle的卸载

  1. 减少内存的使用
  2. 有可能导致丢失
  3. 在切换场景,或者确定不使用的时候卸载
    AssetBundle.Unload(true) //卸载AssetBundle文件的内存镜像,且包含所有Load创建出来的对象
    AssetBundle.Unload(false) //卸载AssetBundle文件的内存镜像,但是除了Load创建出来的对象
    Reources.UnloadAsset(Object) //释放已加载的资源Object
    Resources.UnloadUnusedAssets //卸载所有没有被场景引用的资源对象
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/82349
推荐阅读
相关标签
  

闽ICP备14008679号