Unity2021 AssetBundle资源打包
AssetBundle是一种动态地资源加载方式。如果一次性地把资源导到游戏里,会使得游戏过大。可以把一些资源(例如:预制体、image、材质、music)与游戏主体分离,然后把这些分离的资源放到服务器上。当游戏需要该资源的时候就从服务器加载该资源,从而实现了资源的动态更新。
1. 打包的主要步骤
-
设置打包的对象
-
生成AssetBundle
-
上传到服务器
-
下载AssetBundle
-
加载对象
-
使用对象
2.设置打包对象
-
新建Prefabs文件夹,把图片放在Prefabs文件夹中。
-
新建一个材质球,把材质球添加到beijing中。
-
点击beijing预制体,可以看到Inspector窗口的右下角有个AssetBudle选项,第一个下拉菜单设置打包名称,第二个设置拓展名,都可以通过new自定义。
-
在这里,把三幅图片预制体都设置成allres打包名,以及u3d拓展名。
3.生成AssetBundle
using System.IO;
using UnityEngine;
using UnityEditor;
public class MyTools : Editor
[MenuItem("Tools/CreateBundle")]
static void CreateAssetBundle()
string path = "AB";//写入文件
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
//path:打包路径,BuildAssetBundleOptions.None:打包方式, BuildTarget.StandaloneWindows64:打包的目标平台
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
Debug.Log("Created Bundle!");
}
-
设置完成后,经过引擎的编译,编辑栏上会出现Tools工具栏,点击Tools->CreateBundle,就会在工程目录下生成AB文件夹,里面有各种刚刚设置好的打包对象资源。
-
u3d拓展名的文件为资源文件。
-
manifest文件为资源的一些信息
-
①为资源路径。
-
②为依赖对象的路径,因为beijing预制体绑定了一个材质,因此此依赖对象也使beijing预制体的材质对象。
4.读取打包资源
读取打包资源,一般有4种方法。分别为从内存种读取、从文件中读取、通过WWW方式读取、unityWebRequest读取(推荐)。
1. 从内存中读取
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
// Start is called before the first frame update
void Start()
StartCoroutine(fromMemory());
//StartCoroutine(fromFile()); //读取单个文件
//StartCoroutine(fromAllFile());//读取多个文件
//StartCoroutine(fromWWW1());
//StartCoroutine(fromWWW2());
//StartCoroutine(fromunityWebRequest());
// Update is called once per frame
void Update()
IEnumerator fromMemory()
string path = @"D:\Unity3d\Project\AssetBundleDemo\AB\background.u3d";
string matpath = @"D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
byte[] bytes = File.ReadAllBytes(path);
byte[] matbytes = File.ReadAllBytes(matpath);
AssetBundle assetBundle = AssetBundle.LoadFromMemory(bytes);//以内存的方式加载
AssetBundle matassetBundle = AssetBundle.LoadFromMemory(matbytes);//材质不需要实例化,只需要加载到内存就可以了
GameObject prefabGo = assetBundle.LoadAsset("beijing") as GameObject;//实例化游戏对象
GameObject.Instantiate(prefabGo);
yield return null;
}
-
点击运行,beijing的资源和beijing所依赖的材质都加载到场景了。
2. 从文件中读取
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
// Start is called before the first frame update
void Start()
//StartCoroutine(fromMemory());
StartCoroutine(fromFile()); //读取单个文件
//StartCoroutine(fromAllFile());//读取多个文件
//StartCoroutine(fromWWW1());
//StartCoroutine(fromWWW2());
//StartCoroutine(fromunityWebRequest());
IEnumerator fromFile()
string path = @"D:\Unity3d\Project\AssetBundleDemo\AB\background.u3d";
string matpath = @"D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
AssetBundle matassetBundle = AssetBundle.LoadFromFile(matpath);
GameObject preobj = assetBundle.LoadAsset("beijing") as GameObject;
GameObject.Instantiate(preobj);
yield return null;
}
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
// Start is called before the first frame update
void Start()
//StartCoroutine(fromMemory());
//StartCoroutine(fromFile()); //读取单个文件
StartCoroutine(fromAllFile());//读取多个文件
//StartCoroutine(fromWWW1());
//StartCoroutine(fromWWW2());
//StartCoroutine(fromunityWebRequest());
IEnumerator fromAllFile()
string path = @"D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
string matpath = @"D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
Object[] objlist = assetBundle.LoadAllAssets();
foreach (var obj in objlist)
GameObject.Instantiate(obj as GameObject);
AssetBundle matassetBundle = AssetBundle.LoadFromFile(matpath);
yield return null;
}
3.通过WWW方式读取
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
// Start is called before the first frame update
void Start()
//StartCoroutine(fromMemory());
//StartCoroutine(fromFile()); //读取单个文件
//StartCoroutine(fromAllFile());//读取多个文件
StartCoroutine(fromWWW1());
//StartCoroutine(fromWWW2());
//StartCoroutine(fromunityWebRequest());
//WWW无缓存机制
IEnumerator fromWWW1()
//物体部分
string path = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
WWW www = new WWW(path);
yield return www;
//如果错误信息不空,则打印错误信息,并且中断
if (!string.IsNullOrEmpty(www.error))
Debug.Log(www.error);
yield break;
AssetBundle asset = www.assetBundle;
GameObject pre = asset.LoadAsset("beijing") as GameObject;
GameObject.Instantiate(pre);
//材质部分
string matpath = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
WWW matwww = new WWW(matpath);
if (!string.IsNullOrEmpty(matwww.error))
Debug.Log(matwww.error);
yield break;
AssetBundle matasset = matwww.assetBundle;
www.Dispose();
www = null;
matwww.Dispose();
matwww = null;
yield return null;
}
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
// Start is called before the first frame update
void Start()
//StartCoroutine(fromMemory());
//StartCoroutine(fromFile()); //读取单个文件
//StartCoroutine(fromAllFile());//读取多个文件
//StartCoroutine(fromWWW1());
StartCoroutine(fromWWW2());
//StartCoroutine(fromunityWebRequest());
//WWW缓存机制
IEnumerator fromWWW2()
//物体部分
string path = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
WWW www = WWW.LoadFromCacheOrDownload(path, 1);//如果缓存中有对应的版本,则直接从缓存中读取,如果没有则返回一个错误信息
//如果错误信息不空,则打印错误信息,并且中断
//得到错误信息后,可以重定向路径
if (!string.IsNullOrEmpty(www.error))
Debug.Log(www.error);
yield break;
AssetBundle asset = www.assetBundle;
GameObject pre = asset.LoadAsset("beijing") as GameObject;
GameObject.Instantiate(pre);
//材质部分
string matpath = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
WWW matwww = WWW.LoadFromCacheOrDownload(matpath,1);
if (!string.IsNullOrEmpty(matwww.error))
Debug.Log(matwww.error);
yield break;
AssetBundle matasset = matwww.assetBundle;
www.Dispose();
www = null;
matwww.Dispose();
matwww = null;
yield return null;
}
4.通过unityWebRequest读取
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
// Start is called before the first frame update
void Start()
//StartCoroutine(fromMemory());
//StartCoroutine(fromFile()); //读取单个文件
//StartCoroutine(fromAllFile());//读取多个文件
//StartCoroutine(fromWWW1());
//StartCoroutine(fromWWW2());
StartCoroutine(fromunityWebRequest());
//unityWebRequest
IEnumerator fromunityWebRequest()
//物体部分
string path = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
UnityWebRequest unityWebRequest;
unityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(path);
yield return unityWebRequest.SendWebRequest();//发送请求获取资源
AssetBundle asset = DownloadHandlerAssetBundle.GetContent(unityWebRequest);//获取上面请求得到的资源
GameObject pre = asset.LoadAsset("beijing") as GameObject;
GameObject.Instantiate(pre);
//材质部分
string matpath = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
UnityWebRequest matunityWebRequest;
matunityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(matpath);
yield return matunityWebRequest.SendWebRequest();
AssetBundle matasset = DownloadHandlerAssetBundle.GetContent(matunityWebRequest);
yield return null;