一、前言
这几天在研究AssetBundle资源打包盒解析加载,也踩过很多坑,参考过很多人的文章 发现很多人关于AssetBundle的文章不是API过时了不能用,就是有点乱 也不是有点乱,就是摸不着头脑,让人不能快速的get到这个东西如何使用 所以我特意在踩过坑之后把我这个学到的经验分享给大家。
PS: 一把辛酸泪
二、参考文章
1.雨松大大的Unity3D研究院之Assetbundle的实战(六十三)2.Unity AssetBundle爬坑手记3.Unity5自动命名Assetbundle并打包4.5.0后版本的AssetBundle 使用5.Unity AssetBundle爬坑手记
6.再详细的介绍一下Unity5的AssetBundle7. Unity3D研究院之Assetbundle的实战(六十一)8.Unity5 新AssetBundle打包方式 BuildPipeline.BuildAssetBundles9.Unity最新版打包AssetBundle和加载的方法10.Unity中 BundleAsset资源的打包和解析加载
PS:从参考的文章就知道踩了多少坑了
三、AssetBundle打包方式
3.1 API
- BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
- BuildAssetBundles(string outputPath,AssetBundleBuild[] builds,BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
3.2 参数说明
outputPath:包Bundle后存储的目录,如:Assets/AssetBundles,这个文件夹不会自动创建,如果它不存在的话,函数将会失败 BuildAssetBundleOptions:Bundle打包方式,none没有任何特殊选项,UncompressedAssetBundle在构建Bundle时不要压缩数据等等 BuildTarget:构建平台,如iphone,windows,android等
AssetBundleBuild[]:这个类与BuildAssetBundles一起使用。指定一个Bundle包的名称assetBundleName和它将包含的资源(如多张图片、音频等)的名称。 被传递给函数的AssetBundleBuild[]元素数组被称为“构建映射”,并作为指定编辑器包内容的替代方法。 AssetBundleBuild[]变量: addressableNames:返回所有的addressableName数组
assetBundleName:AssetBundle的名字
assetBundleVariant:AssetBundle的扩展名如.unity
AssetBundle:指定属于一个addressableName名字的所有资源名字,是一个数组,也就是一个addressableName名字下包含的所有资源名字
3.3 例子
1.新建一个脚本PackBundles.cs,放到Editor文件夹中
using System.Collections.Generic; using System.IO; using UnityEditor; public class PackBundles : Editor { //选定资源打包 [MenuItem("PackBundles/PackBundles")] static void PutBundleAssetes() { //初始化一个AssetBundleBuild表 List<AssetBundleBuild> buildMap = new List<AssetBundleBuild>(); AssetBundleBuild build = new AssetBundleBuild(); //设置AssetBundleBuild的名字和资源路径 build.assetBundleName = "123.unity3d"; build.assetNames = new[] { "Assets/Textures/123.jpg" }; //添加进表 buildMap.Add(build); //将这些资源包放在一个名为ABs的目录下 string assetBundleDirectory = "Assets/ABs"; //如果目录不存在,就创建一个目录 if (!Directory.Exists(assetBundleDirectory)) { Directory.CreateDirectory(assetBundleDirectory); } //资源打包 BuildPipeline.BuildAssetBundles(assetBundleDirectory, buildMap.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); } //全部打包 [MenuItem("PackBundles/AllPackBundles")] static void PutBundleAssetesAll() { //将这些资源包放在一个名为ABs的目录下 string assetBundleDirectory = "Assets/ABs"; //如果目录不存在,就创建一个目录 if (!Directory.Exists(assetBundleDirectory)) { Directory.CreateDirectory(assetBundleDirectory); } BuildPipeline.BuildAssetBundles(assetBundleDirectory,BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); } } 复制代码
2.运行
首先Textures文件夹中存放一张123.jpg的图片
点击PackBundles
第二种,全部打包AllPackBundles 需要先在编辑器设置好参数
四、AssetBundle解析加载
4.1 API讲解
4.1.1 加载AssetBundle的API
4.1.2 参数说明
path: 读取AssetBundle的目录 crc : 校验用参数 offset: 这个值指定从哪里开始读取AssetBundle
//从网上加载AssetBundle包 public static UnityWebRequest GetAssetBundle(string uri, uint crc);
public static UnityWebRequest GetAssetBundle(string uri, uint version, uint crc);
public static UnityWebRequest GetAssetBundle(string uri, Hash128 hash, uint crc); public static UnityWebRequest GetAssetBundle(string uri, CachedAssetBundle cachedAssetBundle, uint crc);
4.1.3 参数说明
uri:AssetsBundle包的网络地址:(可以是本地file:) crc:0如果不为0,将会进行校验 version:一个整数版本号 hash:一个版本散列 cachedAssetBundle:用于将给定版本的AssetBundle下载到自定义缓存路径的结构
4.2 加载包中资源API
//加载AssetBundle包的资源 public Object LoadAsset(string name); public Object LoadAsset( string name, Type type); public T LoadAsset( string name); public Object[] LoadAllAssets( Type type); public Object[] LoadAllAssets(); public T[] LoadAllAssets(); public Object LoadAllAssetsAsync(); public Object LoadAssetAsync( string name);
4.2.1 参数说明
name:从AssetBundle包中加载名字为name的资源,返回object Type:加载包内所有类型为type的资源 LoadAllAssets:加载包中所有资源 LoadAssetAsync: 异步加载包中所有资源
4.3 其他API
Path.Combine(string, string) 连接两个字符串 Application.streamingAssetsPath输出 E:/UnityProject/ARVR/Workspace/MyCharacter/Assets/StreamingAssets Application.dataPath输出 E:/UnityProject/ARVR/Workspace/MyCharacter/Assets
4.2 从网上下载资源
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LoadBundles : MonoBehaviour { GameObject go; void Start() { StartCoroutine(Load()); } IEnumerator Load() { //从远程服务器上进行下载和加载 WWW www = new WWW("ftp://123.778.1.128/cube.unity3d"); //等待文件下载完毕 yield return www; //加载数据并赋值给AssetBundle AssetBundle bundle = www.assetBundle; //LoadAssetAsync异步加载包中资源传递给request,request中存放的是名字为Cube.prefab的数据 AssetBundleRequest request = bundle.LoadAssetAsync("Cube.prefab", typeof(GameObject)); go = Instantiate(request.asset as GameObject, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject; yield return request; //释放资源 www.Dispose(); } } 复制代码
4.3 从本地下载资源
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LoadBundles : MonoBehaviour { GameObject go; void Start() { StartCoroutine(Load()); } IEnumerator Load() { //从本地文件中加载 WWW www = new WWW("file://D:/Frank/UnityProject/Demo-1/Assets/ABs/cube01.unity3d"); //等待文件下载完毕 yield return www; //加载数据并赋值给AssetBundle AssetBundle bundle = www.assetBundle; //LoadAssetAsync异步加载包中资源传递给request,request中存放的是名字为Cube.prefab的数据 AssetBundleRequest request = bundle.LoadAssetAsync("Cube.prefab", typeof(GameObject)); go = Instantiate(request.asset as GameObject, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject; yield return request; www.Dispose(); } } 复制代码
五、测试例子
##步骤:
1.新建脚本PackBundles.cs放在Editor文件中
编辑脚本
2. 新建脚本LoadBundles.cs随意放那个文件夹都行 编辑脚本:
3. 打包资源
4. 把加载脚本LoadBundles.cs挂载在场景中的任意物体上
5. 成功加载生成
PS:途中的Cube是我设置好的Cube预制体,加上了一个材质
OK,文章结束
PS:如果想要加载网上资源,就把打包好的包放到服务器上,然后通过地址,WWW类下载下来,解析加载就行了。