一、设置assetBundleName
二、构建AssetBundle包
三、上传AssetBundle到服务器
四、把AssetBundle放到本地
五、操作AssetBundle
六、完整例子
七、AssetBundle Manager管理工具
八、备注知识

一、设置assetBundleName

如果没有设置AssetBundleName,会打包所有的Assets下的资源,如果设置,就只打包设置了名字的资源

1、在unity编辑器界面手动设置


输入所需的AssetBundle名称。请注意,AssetBundle名称确实支持一种类型的文件夹结构,这取决于您键入的内容。要添加子文件夹,将文件夹名称以“/”分隔。例如:AssetBundle名称“environment/ forest”将在environment子文件夹下创建一个名为forest的包

2、遍历所有要打包的资源,通过代码修改assetBundleName       

第一步:先获取你要打包的资源的完整目录

       方法1:

先用Selection.objects返回场景中所有的对象,

然后用AssetDatabase.GetAssetPath(selected)获取对象完整目录

方法2:

用AssetPostprocessor的OnPostprocessAllAssets方法

方法3:

用IO流的DirectoryInfo.GetFileSystemInfos()

和FileInfonfo获取完整目录(这种方法要注意:获取到的目录如果是”\”或者”//”要替换为“/”)

第二步:用AssetImporter asset= AssetImporter.GetAtPath(path);方法获取AssetImporter

第三步:用asset.assetBundleName=“text”设置AssetBundleName

 

有以下三种获取目录然后设置assetBundleName的方法

//Selection.objects返回场景中所有的对象Object[] selects = Selection.objects;foreach (Object selected in selects){//返回所有对象相对于工程目录的存储路径如Assets/_Scenes/Main.unitystring path = AssetDatabase.GetAssetPath(selected);//把一个目录的对象检索为AssetImporterAssetImporter asset = AssetImporter.GetAtPath(path);asset.assetBundleName = selected.name; //设置Bundle文件的名称    asset.assetBundleVariant = "unity3d";//设置Bundle文件的扩展名    asset.SaveAndReimport();}AssetDatabase.Refresh();
using UnityEngine;
using System.Collections;
using UnityEditor;
//文件描述:自动设置Assetbundle名字为文件夹名_文件名.unity3d;
public class AutoSetTextureUISprite : AssetPostprocessor
{static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths){foreach (var str in importedAssets){if (!str.EndsWith(".cs")){AssetImporter importer = AssetImporter.GetAtPath(str);importer.assetBundleName = str;}}foreach (var str in deletedAssets){if (!str.EndsWith(".cs")){AssetImporter importer = AssetImporter.GetAtPath(str);importer.assetBundleName = str;}}for (var i = 0; i < movedAssets.Length; i++){//Debug.Log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]);}}
}
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;/// <summary>
/// 把Resource下的资源打包成.unity3d 到StreamingAssets目录下
/// </summary>
public class Builder : Editor
{public static string sourcePath = Application.dataPath + "/Resources";const string AssetBundlesOutputPath = "Assets/StreamingAssets";//[MenuItem("Tools/AssetBundle/Build")]public static void BuildAssetBundle(){ClearAssetBundlesName();Pack(sourcePath);string outputPath = Path.Combine(AssetBundlesOutputPath, Platform.GetPlatformFolder(EditorUserBuildSettings.activeBuildTarget));if (!Directory.Exists(outputPath)){Directory.CreateDirectory(outputPath);}//根据BuildSetting里面所激活的平台进行打包  BuildPipeline.BuildAssetBundles(outputPath, 0, EditorUserBuildSettings.activeBuildTarget);AssetDatabase.Refresh();Debug.Log("打包完成");}/// <summary>  /// 清除之前设置过的AssetBundleName,避免产生不必要的资源也打包  /// 之前说过,只要设置了AssetBundleName的,都会进行打包,不论在什么目录下  /// </summary>  static void ClearAssetBundlesName(){int length = AssetDatabase.GetAllAssetBundleNames().Length;Debug.Log(length);string[] oldAssetBundleNames = new string[length];for (int i = 0; i < length; i++){oldAssetBundleNames[i] = AssetDatabase.GetAllAssetBundleNames()[i];}for (int j = 0; j < oldAssetBundleNames.Length; j++){AssetDatabase.RemoveAssetBundleName(oldAssetBundleNames[j], true);}length = AssetDatabase.GetAllAssetBundleNames().Length;Debug.Log(length);}static void Pack(string source){DirectoryInfo folder = new DirectoryInfo(source);FileSystemInfo[] files = folder.GetFileSystemInfos();int length = files.Length;for (int i = 0; i < length; i++){if (files[i] is DirectoryInfo){Pack(files[i].FullName);}else{if (!files[i].Name.EndsWith(".meta")){file(files[i].FullName);}}}}static void file(string source){string _source = Replace(source);string _assetPath = "Assets" + _source.Substring(Application.dataPath.Length);string _assetPath2 = _source.Substring(Application.dataPath.Length + 1);//Debug.Log (_assetPath);  //在代码中给资源设置AssetBundleName  AssetImporter assetImporter = AssetImporter.GetAtPath(_assetPath);string assetName = _assetPath2.Substring(_assetPath2.IndexOf("/") + 1);assetName = assetName.Replace(Path.GetExtension(assetName), ".unity3d");//Debug.Log (assetName);  assetImporter.assetBundleName = assetName;}static string Replace(string s){return s.Replace("\\", "/");}
}public class Platform
{public static string GetPlatformFolder(BuildTarget target){switch (target){case BuildTarget.Android:return "Android";case BuildTarget.iOS:return "IOS";case BuildTarget.WebPlayer:return "WebPlayer";case BuildTarget.StandaloneWindows:case BuildTarget.StandaloneWindows64:return "Windows";case BuildTarget.StandaloneOSXIntel:case BuildTarget.StandaloneOSXIntel64:case BuildTarget.StandaloneOSXUniversal:return "OSX";default:return null;}}}

二、构建AssetBundle

1、在Assets中创建一个名为Editor的文件夹,并将一个脚本放在文件夹中

2、类要继承Editor,引用命名空间using UnityEditor;

3、创建菜单目录:[MenuItem("Assets/Build AssetBundles")]

4、调用打包方法

①用AssetBundleBuild类的方法
BuildAssetBundles(string outputPath, BuildAssetBundleOptionsassetBundleOptions, BuildTargettargetPlatform);
或者
BuildAssetBundles(string outputPath,AssetBundleBuild[] builds,BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);

②参数说明:

outputPath:打包Bundle后存储的目录,如:Assets/AssetBundles,这个文件夹不会自动创建,如果它不存在的话,函数将会失败,Directory.Exists(string path)判断目录是否存在,Directory.CreateDirectory(stringpath)创建目录

BuildAssetBundleOptions:Bundle打包方式,none没有任何特殊选项,UncompressedAssetBundle在构建Bundle时不要压缩数据等等

BuildTarget:构建平台,如iphone,windows,android等

AssetBundleBuild[]:看备注知识5
③返回值:AssetBundleManifest,看备注知识65、备注知识:AssetBundleBuild这个类与BuildAssetBundles一起使用。指定一个Bundle包的名称assetBundleName和它将包含的资源(如多张图片、音频等)的名称。被传递给函数的AssetBundleBuild[]元素数组被称为“构建映射”,并作为指定编辑器包内容的替代方法。变量:

addressableNames:返回所有的addressableName数组    assetBundleName:AssetBundle的名字    assetBundleVariant:AssetBundle的扩展名如.unity       AssetBundle:指定属于一个addressableName名字的所有资源名字,是一个数组,也就是一个addressableName名字下包含的所有资源名字例子:在后面

6、备注知识AssetBundleManifest
包含所有创建Bundle包信息

⑴公开方法

GetAllAssetBundles返回所有的assetbundlenames,是一个string[]数组

GetAllAssetBundlesWithVariant返回所有使用给定扩展名的assetbundlenames,是一个string[]数组

GetAllDependencies(string assetBundleName);:获取所有与指定AssetBundle包存在依赖关系的AssetBundless。也就是给一个assetBundleName,获取所有与他有关系的assetBundleName,返回一个string[]数组

GetDirectDependencies(string assetBundleName):获取所有与指定AssetBundle包存在直接联系的AssetBundless。也就是给一个assetBundleName,获取所有与他有直接关系的assetBundleName,返回一个string[]数组

GetAssetBundleHash

⑵当找到这个对象后就可以对它进行操作

7、例子

第一个方法

// 创建一个Windows AssetBundle包
using UnityEngine;
using UnityEditor;
using System.IO;
public class BuildAssetBundlesExample : MonoBehaviour
{//创建编辑器菜单目录[MenuItem("Example/Build Asset Bundles")]static void BuildABs(){//将这些资源包放在一个名为ABs的目录下string assetBundleDirectory = "Assets/ABs";//如果目录不存在,就创建一个目录if (!Directory.Exists(assetBundleDirectory)){Directory.CreateDirectory(assetBundleDirectory);}BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);}
}

第二个方法

using UnityEngine;
using UnityEditor;
using System.IO;
public class BuildAssetBundlesBuildMapExample : MonoBehaviour
{[MenuItem("Example/Build Asset Bundles Using BuildMap")]static void BuildMapABs(){// 创建映射数组AssetBundleBuild[] buildMap = new AssetBundleBuild[2];//修改assetBundleName第一个buildMap[0].assetBundleName = "enemybundle";//assetBundleName = "enemybundle"下的所有资源名称数组string[] enemyAssets = new string[2];enemyAssets[0] = "Assets/Textures/char_enemy_alienShip.jpg";enemyAssets[1] = "Assets/Textures/char_enemy_alienShip-damaged.jpg";buildMap[0].assetNames = enemyAssets;//修改assetBundleName第二个buildMap[1].assetBundleName = "herobundle";//assetBundleName = "herobundle"下的所有资源名称数组string[] heroAssets = new string[1];heroAssets[0] = "char_hero_beanMan";buildMap[1].assetNames = heroAssets;//创建Bundle包//将这些资源包放在一个名为ABs的目录下string assetBundleDirectory = "Assets/ABs";//如果目录不存在,就创建一个目录if (!Directory.Exists(assetBundleDirectory)){Directory.CreateDirectory(assetBundleDirectory);}BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);}
}

三、上传AssetBundle到服务器

四、把AssetBundle放到本地

五、操作AssetBundle

1、从磁盘目录加载AssetBundle包

⑴AssetBundle放在本地

public static AssetBundle LoadFromFile(string  path uint crc = 0, ulong offset= 0);

说明:从path目录同步加载AssetBundle,返回类型

AssetBundle(LoadFromFileAsync是异步加载)

参数:path读取AssetBundle的目录

crc 校验用参数

offset这个值指定从哪里开始读取AssetBundle,

通常为0

⑵ AssetBundle放在网络

引用using UnityEngine.Networking;命名空间

UnityWebRequest.GetAssetBundle()方法看后面的详细介绍

2、加载AssetBundle包之后,加载包内资源

注意:加载要用协程,否则你不知道是否加载完毕

⑴加载一个资源

AssetBundle类

public Object LoadAsset(string name);

从AssetBundle包中加载名字为name的资源,返回object

public Object LoadAsset(string name, Type type);

加载一个包内名字为name,类型为type的资源

public T LoadAsset(string name);

搞不懂,也是加载名字为name类型为T的资源

⑵加载包内的多个资源

AssetBundle类

public Object[] LoadAllAssets(Type type);

加载包内所有类型为type的资源

public Object[] LoadAllAssets();

加载包内的所有资源

public T[] LoadAllAssets();

搞不懂,也是加载类型为T的资源

⑶备注,上面的方法是同步加载,还有异步加载方法

LoadAllAssetsAsync,LoadAssetAsync

3、从包内加载资源以后,可以对这个对象进行各种操作了

4、备注知识点

⑴Path.Combine(string, string) 连接两个字符串

⑵ Application 访问应用程序运行时数据

Application.streamingAssetsPath输出

E:/UnityProject/ARVR/Workspace/MyCharacter/Assets/StreamingAssets

Application.dataPath输出

E:/UnityProject/ARVR/Workspace/MyCharacter/Assets

值得注意的是如果在PC上使用时需要在每个文件夹前加入斜杠,如:

string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName;

例子:注意:加载要用协程,否则你不知道是否加载完毕

using UnityEngine;
using System.Collections;
using System.IO;
public class LoadFromFileExample : MonoBehaviour
{void Start(){//从文件夹里加载包var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle"));if (myLoadedAssetBundle == null){Debug.Log("Failed to load AssetBundle!");return;}//从Bundle包中加载名字为:MyObject的资源,加载为GameObjectvar prefab = myLoadedAssetBundle.LoadAsset<GameObject>("MyObject");//实例化Instantiate(prefab);//卸载包中资源的内存myLoadedAssetBundle.Unload(false);}
}

5、AssetBundle放在网络

⑴创建一个UnityWebRequest,通过HTTP GET下载一个Unity资产包

引用using UnityEngine.Networking;命名空间

UnityWebRequest.GetAssetBundle()方法

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);

返回值:UnityWebRequest

参数:

uri:AssetsBundle包的网络地址:(可以是本地file:)

crc:0,如果不为0,将会进行校验

version:一个整数版本号

hash:一个版本散列

cachedAssetBundle:用于将给定版本的AssetBundle下载到自定义缓存路径的结构

⑵处理上一步的UnityWebRequest

用DownloadHandlerAssetBundle.GetContent()方法

public static AssetBundle GetContent(Networking.UnityWebRequest www);

www:就是上一步处理的UnityWebRequest

AssetBundle:返回值类型

例子

IEnumerator InstantiateObject(){string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName;UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0);yield return request.Send();AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);GameObject cube = bundle.LoadAsset<GameObject>("Cube");GameObject sprite = bundle.LoadAsset<GameObject>("Sprite");Instantiate(cube);Instantiate(sprite);
}

六、完整例子

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEngine.UI;
using UnityEngine.Networking;
public class NewBehaviourScript : MonoBehaviour {Image image1;Image Image2;void Start () {image1 = GameObject.Find("Image (1)").GetComponent<Image>();Image2 = GameObject.Find("Image (2)").GetComponent<Image>();StartCoroutine(InstantiateObject());StartCoroutine(InstantiateObjects());}//一个包有多个资源IEnumerator InstantiateObjects(){//texture是一个文件夹,里面放了多张图片string uri = "file:///" + Application.dataPath + "/AssetsBundles/texture";UnityWebRequest request = UnityWebRequest.GetAssetBundle(uri, 0);yield return request.Send();AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);Object[] obj = bundle.LoadAllAssets(typeof(Sprite));Sprite[] sprite = new Sprite[obj.Length];for (int i = 0; i < obj.Length; i++){sprite[i] = obj[i] as Sprite;}this.gameObject.GetComponent<Image>().sprite = sprite[0];image1.sprite = sprite[1];//string path = Application.dataPath + "/AssetsBundles/texture";//AssetBundle assetbundle = AssetBundle.LoadFromFile(path, 0, 0);//yield return assetbundle;//if (assetbundle == null)//{//    print("加载Bundle为空");//}//加载类型为sprite的图片,否则一张图片会加载成两个//Object[] obj =assetbundle.LoadAllAssets(typeof(Sprite));//Sprite[] sprite = new Sprite[obj.Length];//for (int i = 0; i < obj.Length; i++)//{//    sprite[i] = obj[i] as Sprite;//}//this.gameObject.GetComponent<Image>().sprite = sprite[0];//image1.sprite = sprite[1];}//一个包有一个资源IEnumerator InstantiateObject(){//用UnityWebRequest读取//string uri = "file:///" + Application.dataPath + "/AssetsBundles/gress";//UnityWebRequest request = UnityWebRequest.GetAssetBundle(uri, 0);//yield return request.Send();//AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);//GameObject cube = bundle.LoadAsset<GameObject>("gress");//Sprite sprite = bundle.LoadAsset<Sprite>("gress");//this.gameObject.GetComponent<Image>().sprite = sprite;//用AssetBundle读取string path = Application.dataPath + "/AssetsBundles/gress";AssetBundle assetbundle = AssetBundle.LoadFromFile(path, 0, 0);yield return assetbundle;if (assetbundle == null){print("加载Bundle为空");}Sprite sprite = assetbundle.LoadAsset<Sprite>("gress");Image2.sprite = sprite;}// Update is called once per framevoid Update () {}
}

七、AssetBundle Manager管理工具

 

AssetBundle Manage是一个管理AssetBundle的工具,在官方资源商店寻找

文档说明

https://docs.unity3d.com/Manual/AssetBundles-Manager.html

下载地址

https://www.assetstore.unity3d.com/en/#!/content/45836

AssetBundle Manager是一个由Unity制作的工具,它可以使AssetBundle更加高效。

下载并导入 AssetBundle Manager 包不仅增加了加载和使用 AssetBundle 的新 API ,而且还添加了一些编辑器功能来简化工作流。这个功能可以在 Assets 菜单选项下找到。

八、备注

1、基于平台的加载AssetBundle方法

AssetBundle.LoadFromMemoryAsync

AssetBundle.LoadFromFile

WWW.LoadfromCacheOrDownload

UnityWebRequest DownloadHandlerAssetBundle(Unity 5.3 or newer)

方法:https://docs.unity3d.com/Manual/AssetBundles-Native.html

2、一些知识点网址

Unity5.X新版AssetBundle使用方案及策略

http://www.cnblogs.com/jiangshuai52511/p/6437239.html

Unity5新的AssetBundle系统使用心得

http://blog.csdn.net/langresser_king/article/details/44208585

[Unity热更新]unity5中的assetbundle

http://blog.csdn.net/lyh916/article/details/49815871

3、下面的方法未经过测试,先记录下来,待以后查询

(1)、为需要打包到AssetBundle中的资源设置其assetBundleName,有两种方式可以实现这个功能:一是手动在编辑界面对资源一一进行手动设置;二是遍历需要设置的资源目录,通过代码动态设置。显然第二个办法更加方便,具体的步骤如下:

a.遍历要打包的资源目录,找到需要打包的预设或者资源;

b.设置资源的assetBundleName属性;

c.通过AssetDatabase.GetDependencies(stringpath)方法逐个找到资源的依赖资源路径;

d.使用AssetDatabase.AssetPathToGUID(stringpath)计算出每个资源的唯一ID,然后将此ID当做assetBundleName赋予每个依赖资源;

e.调用BuildPipeline.BuildAssetBundles(stringoutputPath)打包到指定位置。

(2).资源加载:

由于依赖关系存在于manifest中,所以加载资源之前,需要先加载manifest文件。

Unity最新版打包AssetBundle和加载的方法相关推荐

  1. unity当前项目里面AssetBundle和加载的方法总结

    2017年10月14日 19:24:14 醉忘天涯一线天 阅读数:9021 出处:https://blog.csdn.net/lmyfx/article/details/78236225 版权声明:本 ...

  2. [FairyGUI][Unity]FGUI资源打包AssetBundle

    参考资料3 将发布后的文件打包为两个AssetBundle,即定义文件和资源各打包为一个bundle(desc_bundle+res_bundle).这样做的好处是一般UI的更新都是修改元件位置什么的 ...

  3. 游戏资源差异化热更新及加密全攻略(Assetbundle 打包 AssetBundle 加载 AssetBundle 加密)

    游戏热更新资源加密的必要性 unity中资源热更新还是Assetbundle为主,资源使用越来越广泛,ab包里可以包含图片.视频或者脚本,都是游戏的知识财产,如果被破解者或者竞争对手解开,拿到里面的内 ...

  4. unity保存加载慢_掌握Unity 5中的保存和加载功能

    unity保存加载慢 Thanks to Vincent Quarles for kindly helping to peer review this article. 感谢Vincent Quarl ...

  5. python环境的打包与加载

    目录 1 pip方式 1.1 requirements.txt文件的生成 1.2 requirements.txt环境的加载: 2 conda方式 2.1 env.yml文件的生成 2.2 env.y ...

  6. Unity资源处理机制(Assets/WWW/AssetBundle/...)读取和加载资源方式详解

    Unity资源机制 1.概述 本文意在阐述Unity资源机制相关的信息,以及一些关于个人的理解与试验结果.另外还会提及一些因机制问题可能会出现的异常以及处理建议.大部分机制信息来源于官方文档,另外为自 ...

  7. 关于unity 中使用AssetBundle加载资源,shader偶尔会丢失的问题解决办法

    问题描述: 因为项目中要进行热更新设计,所以用unity官方推荐的打包方式assetbundle进行打包,打包好了以后再电脑上运行正常,但是当发布到android上后发现偶尔场景背景会出现空白,多方查 ...

  8. Unity5.X打包与加载AssetBundle简单示例

    准备与打包AssetBundle: 在Editor内,点击任意prefab或资源文件,在右下角(默认Editor布局)AssetsBundle处可设置此prefab的Assetsbundle属性. 例 ...

  9. Unity中AB包详解(超详细,特性,打包,加载,管理器)

    Unity中的AssetBundle详解 AssetBundle的概念 AssetBundle又称AB包,是Unity提供的一种用于存储资源的资源压缩包. Unity中的AssetBundle系统是对 ...

最新文章

  1. Python 字符串判断字母 数字 大小写
  2. stl的nth_element
  3. LWUIT 简易漂亮的相册
  4. 行业「趋轻」,尚美“共创品牌”推动酒店业进入春天
  5. Tensorfow_yolov3 Intel Realsense D435 图像整合(合并)输入GPU计算耗时测试
  6. 数组中子数组求最大和
  7. 虚拟成像技术_苹果AR头显细节全曝光!微美全息(WIMI.US)光场技术构建AI影像...
  8. HDU1850(Nim游戏)
  9. Linux Makefile
  10. Linux时间date与timedatectl
  11. java list装3组数据_数组转List的3种方法和使用对比!
  12. [转载]ASP.NET 格式化字符串
  13. Rosie's Frankly Speaking
  14. 如何使用phpMyAdmin管理数据库
  15. Tapestry5.3使用总结
  16. Python 开发音乐下载器实践
  17. 基于C#的超市进销存管理系统设计与实现
  18. mysql 订单表 订单详情表 关联 排序 统计
  19. 制作 img系统镜像的详细方法
  20. 国标、行标、地标、团标、企标

热门文章

  1. java游戏暗金装备_暗黑2装备升级公式图解(暗金装备升级一览表)
  2. 若依 / RuoYi-Vue 前后端分离,前端部署及注意事项
  3. MyBatis学习(二)--利用MyBatis实现CRUD操作
  4. 极坐标梯度公式_梯度的极坐标表达式
  5. 基于GLSL的聚光灯效果的绘制
  6. 怎么设置不同页的页眉
  7. 产品创新案例分析|大疆如何从初创到无人机帝国的进阶之路
  8. win电脑C/D盘清理技巧
  9. 昨天学了js的控制css样式,自己做了个算卦小程序
  10. 学习 Java8 函数式编程 (二)