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文件为资源的一些信息
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;
}
}
3.通过WWW方式读取
-
无缓存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;
}
}
|