一、Unity引擎的AssetBundle(资源管理技术)的介绍
①Unity引擎的AssetBundle(资源管理技术)是通过动态加载与卸载资源,极大节约游戏所占空间,且实现游戏发布后关于资源的后续更新与完善的实时更新技术。
② AssetBundles可以将Unity中所创建的文件或任何资源导出成为一种特定的文件格式,这些文件导出后使用的是一种特定的文件类型(.assetbundle/.unity3d),这些特定格式的文件能够在需要的时候加载到场景中。(这些特定格式的文件可以是:模型、贴图、声音文件;甚至是场景文件)。
③AssetBundle可以分为四个部件
《1》创建AssetBundles资源
《2》上传资源服务器端
《3》下载AssetBundles资源
《4》加载与卸载AssetBundles资源
二、创建AssetBundle
①定位需要打包与加载的资源,可以是任意类型(如贴图、材质、音频、预设等),如下所示:
②编写打包脚本(BuildAssetBundles.cs) ,必须将该脚本放置在"Editor"的特殊文件夹下
/***
*
* Title: "AssetBundle工具包"项目
* 给AssetBundle目录(资源)打包
*
* Description:
* 功能:[本脚本的主要功能描述]
*
* Date: 2018
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
public class BuildAssetBundle{
/// <summary>
/// 打包生成所有AssetBundles
/// </summary>
[MenuItem("AssetBundleTools/BuildAllAssetBundles")]
public static void BuildAllAB()
{
//(打包)AB的输出路径
string strABOutPathDIR = string.Empty;
strABOutPathDIR = Application.streamingAssetsPath;
if (!Directory.Exists(strABOutPathDIR)){
Directory.CreateDirectory(strABOutPathDIR);
}
//打包生成
BuildPipeline.BuildAssetBundles(strABOutPathDIR,BuildAssetBundleOptions.None,
BuildTarget.StandaloneWindows64);
}
}//Class_end
③单机“BuildAllAssetBundles”后开始打包,大约几秒后再项目视图的StreamingAssets目录下看到我们打包好的文件名称
三、下载AssetBundle资源(采用“非缓存机制”)
《1》Unity2017中具有3种不同的方法来加载已经下载的数据资源
①assetBundle.LoadAsset(); 通过指定assetBundle包名称加载资源
②assetBundle.LoadAssetAsync(); 通过指定assetBundle包名称异步加载资源(加载过程中不会阻碍主线程的运行)
③assetBundle.LoadAllAsset(); 加载所有的assetBundle中包含的资源对象
《2》下载AssetBundle资源(加载与卸载脚本)
/***
*
* Title:
* AssetBundle资源动态加载技术
* 演示AssetBundle基本加载
*
* Description:
* 功能:
* 演示加载AssetBundle且显示资源,一共分两种情形。
* 1: 非“对象预设”资源加载与显示。
* 2: “对象预设”资源加载与显示。
*
* 说明:
* 1: 这里所谓的“基本加载”即在不使用自定义“AssetBundle框架”情况下加载“对象预设”。
* 2: 这里AssetBundle资源,是提前已经打包好的。
*
* Date: 2018
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AssetBundleLoadDemo:MonoBehaviour {
//显示的方位
public Transform TraShowPosition;
//测试更改贴图
public GameObject goCube_ChangeTxt;
/* URL与材质名称 */
//第1组,测试显示“预设体”
private string _ABURL_1;
private string _AssetName_1;
//第2组,测试改变贴图
private string _ABURL_2;
private string _AssetName_2;
private void Awake(){
//对象预设资源路径
_ABURL_1 = "file://" + Application.streamingAssetsPath + "/prefabab.ab";
_AssetName_1 = "SpherePink";
//对象贴图资源路径
_ABURL_2 = "file://" + Application.streamingAssetsPath + "/texturesab";
_AssetName_2 = "unitychan_tile3";
}
private void Start(){
//实验1: 加载AB包,显示简单“预设体”
StartCoroutine(LoadPrefabsFromAB(_ABURL_1, _AssetName_1, TraShowPosition));
//实验2: 加载AB包,显示贴图(材质、音频等)
//StartCoroutine(LoadNonObjFromAB(_ABURL_2, goCube_ChangeTxt,_AssetName_2));
}
/// <summary>
/// (下载且)加载“预设”资源
/// </summary>
/// <param name="ABURL">AssetBundle URL</param>
/// <param name="AssetName">资源名称</param>
/// <param name="showPos">实例化克隆体显示方位</param>
/// <returns></returns>
IEnumerator LoadPrefabsFromAB(string ABURL,string assetaName="",Transform showPos=null)
{
//参数检查
if (string.IsNullOrEmpty(ABURL))
Debug.LogError(GetType()+ "/LoadPrefabsFromAB()/ 输入参数‘AssetBundle URL’为空,请检查!");
using (WWW www=new WWW(ABURL)){
yield return www;
AssetBundle ab = www.assetBundle;
if (ab!=null){
if (assetaName == ""){
//实例化主资源
if (showPos!=null){
//确定显示方位
GameObject tmpClonePrefabs=(GameObject)Instantiate(ab.mainAsset);
tmpClonePrefabs.transform.position = showPos.transform.position;
}
else {
Instantiate(ab.mainAsset);
}
}
else {
//实例化指定资源
if (showPos != null){
//确定显示方位
GameObject tmpClonePrefabs = (GameObject)Instantiate(ab.LoadAsset(assetaName));
tmpClonePrefabs.transform.position = showPos.transform.position;
}
else{
Instantiate(ab.LoadAsset(assetaName));
}
}
//卸载资源(只卸载AssetBundle 包本身)
ab.Unload(false);
}
else {
Debug.LogError(GetType()+ "/LoadPrefabsFromAB()/WWW 下载出错,请检查 AssetBundle URL :"+ABURL+" 错误信息: "+www.error);
}
}
}
/// <summary>
/// (下载且)加载"非GameObject"资源
/// </summary>
/// <param name="ABURL">AssetBundle URL</param>
/// <param name="AssetName">资源名称</param>
/// <returns></returns>
IEnumerator LoadNonObjFromAB(string ABURL, GameObject goShowObj,string AssetName = "")
{
//参数检查
if (string.IsNullOrEmpty(ABURL) || goShowObj==null)
{
Debug.LogError(GetType() + "/LoadTextureFromAB()/ 输入的参数为空,请检查!");
}
using (WWW www = new WWW(ABURL))
{
yield return www;
AssetBundle ab = www.assetBundle;
if (ab != null)
{
if (AssetName=="")
{
goShowObj.GetComponent<Renderer>().material.mainTexture = (Texture)ab.mainAsset;
}
else {
goShowObj.GetComponent<Renderer>().material.mainTexture = (Texture)ab.LoadAsset(AssetName);
}
//卸载资源(只卸载AssetBundle 包本身)
ab.Unload(false);
}
else
{
Debug.LogError(GetType() + "/LoadTextureFromAB()/WWW 下载出错,请检查 AssetBundle URL :" + ABURL + " 错误信息: " + www.error);
}
}
}
}//Class_end
注:本内容来自《Unity3D/2D游戏开发从0到1》29章