一、AssetBundle入門到掌握
1-學前必讀
為熱更新打基礎(xlua\tolua)
學習方法:跟著老師實操。
2-AssetBundle的定義和作用
看官方文檔:安裝有道詞典的記事本功能
1,AssetBundle是一個壓縮包包含模型、貼圖、預制體、聲音、甚至整個場景,可以在遊戲運行的時候被加載;
2,AssetBundle自身保存著互相的依賴關系;
3,壓縮包可以使用LZMA和LZ4壓縮算法,減少包大小,更快的進行網絡傳輸;
4,把一些可以下載內容放在AssetBundle裏面,可以減少安裝包的大小;
3-什麽事AssetBundle?
可以歸為兩點:
1,它是一個存在於硬盤上的文件。可以稱之為壓縮包。這個壓縮包可以認為是一個文件夾,裏面包含了多個文件。這些文件可以分為兩類:serialized file 和 resource files。(序列化文件和源文件)
serialized file:資源被打碎放在一個對象中,最後統一被寫進一個單獨的文件(只有一個)
resource files:某些二進制資源(圖片、聲音)被單獨保存,方便快速加載
2,它是一個AssetBundle對象,我們可以通過代碼從一個特定的壓縮包加載出來的對象。這個對象包含了所有我們當初添加到這個壓縮包裏面的內容,我們可以通過這個對象加載出來使用
4-AssetBundle包使用流程(簡稱AB)
1,指定資源的AssetBundle屬性,在右下角
(xxxa/xxx)這裏xxxa會生成目錄,名字為xxx
2,構建AssetBundle包
3,上傳AB包
4,加載AB包和包裏面的資源
5-使用代碼打包AssetBundle
在Project中創建一個Editor的文件夾,在裏面寫編輯器拓展的代碼
CreateAssetBundle.cs
using UnityEditor;
using System.IO;
public class CreateAssetBundle {
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
//由於unity不會幫我們自動創建目錄,所以我們需要自己創建
string dir = "AssetBundles";
if (Directory.Exists(dir) == false) //如果文件夾不存在
{
Directory.CreateDirectory(dir);
}
BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}
}
再次打包時如果文字相同會自動覆蓋
6.AssetBundle打包註意事項
兩個文件,manifest文件的作用
通過目錄的劃分
scene/wall
7-AssetBundle的加載和使用
新建空物體掛上LoadFromFile.cs
using UnityEngine;
public class LoadFromFile : MonoBehaviour {
void Start () {
AssetBundle ab= AssetBundle.LoadFromFile("AssetBundles/scene/cubewall.unity3d");
//加載一個
GameObject cubePrefab = ab.LoadAsset<GameObject>("cubeWall");
Instantiate(cubePrefab);
//遍歷加載一個
//Object[] objects= ab.LoadAllAssets();
//foreach (Object item in objects)
//{
// Instantiate(item);
//}
}
}
8-AssetBundle分組策略
1,邏輯實體分組
a,一個UI界面或者所有UI界面一個包(這個界面裏面的貼圖和布局信息一個包)
b,一個角色或者所有角色一個包(這個角色裏面的模型和動畫一個包)
c,所有的場景所共享的部分一個包(包括貼圖和模型)
2,按照類型分組
所有聲音資源打成一個包,所有shader打成一個包,所有模型打成一個包,所有材質打成一個包
3,按照使用分組
把在某一時間內使用的所有資源打成一個包。可以按照關卡分,一個關卡所需要的所有資源包括角色、貼圖、聲音等打成一個包。也可以按照場景分,一個場景所需要的資源一個包
9-Assetbundle分組策略總結
1,把經常更新的資源放在一個單獨的包裏面,跟不經常更新的包分離
2,把需要同時加載的資源放在一個包裏面
3,可以把其他包共享的資源放在一個單獨的包裏面
如:共同使用的貼圖放在一個單獨的包中,能優化項目
4,把一些需要同時加載的小資源打包成一個包
5,如果對於一個同一個資源有兩個版本,可以考慮通過後綴來區分 v1 v2 v3 unity3dv1 unity3
10-依賴打包
即為講解上一節的第三點:共同使用的放在一個單獨的包中,能優化項目
11-打包選項(AssetBundle壓縮方式)
1,Build的路徑(隨意只要是在硬盤上都可以的)
2,BuildAssetBundleOptions
BuildAssetBundleOptions.None:使用LZMA算法壓縮,壓縮的包更小,但是加載時間更長。使用之前需要整體解壓。一旦被解壓,這個包會使用LZ4重新壓縮。使用資源的時候不需要整體解壓。在下載的時候可以使用LZMA算法,一旦它被下載了之後,它會使用LZ4算法保存到本地上。
BuildAssetBundleOptions.UncompressedAssetBundle:不壓縮,包大,加載快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4壓縮,壓縮率沒有LZMA高,但是我們可以加載指定資源而不用解壓全部。
註意使用LZ4壓縮,可以獲得可以跟不壓縮想媲美的加載速度,而且比不壓縮文件要小。
BuildTarget
選擇build出來的AB包要使用的平
12-Manifest文件是幹什麽的?
Assets:(所在文件)
Dependences:(依賴文件)
13-資源的依賴關系
先加載依賴包,再加載當前包
14-從內存裏面加載AssetBundle
四個加載的API
1,AssetBundle.LoadFromMemory(從內存下載)
/// <summary>
///LoadFromMemory(從內存中同步加載)
/// </summary>
void Start()
{
string path = "AssetBundles/scene/cubewall.unity3d";
AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
GameObject cubePrefab = ab.LoadAsset<GameObject>("cubeWall");
Instantiate(cubePrefab);
}
AssetBundle.LoadFromMemoryAsync
/// <summary>
/// 第一種加載方式:LoadFromMemoryAsync(從內存中異步加載)
/// </summary>
IEnumerator Start()
{
string path = "AssetBundles/scene/cubewall.unity3d";
AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
yield return request;
AssetBundle ab = request.assetBundle;
GameObject cubePrefab = ab.LoadAsset<GameObject>("cubeWall");
Instantiate(cubePrefab);
}
2,AssetBundle.LoadFromFile(從本地下載)
AssetBundle.LoadFromFileAsync
/// <summary>
/// 第二種加載方式:LoadFromFile(從內存中異步加載)
/// </summary>
IEnumerator Start()
{
string path = "AssetBundles/scene/cubewall.unity3d";
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
yield return request;
AssetBundle ab = request.assetBundle;
//使用裏面的資源
var cubePrefab = ab.LoadAsset<GameObject>("cubeWall");
Instantiate(cubePrefab);
}
3,WWW.LoadFromCacheOrDownload
4,UnityWebRequest
15-使用WWW.LoadFromCacheOrDownload下載AssetBundle
/// <summary>
/// 第三種加載方式:www
/// </summary>
/// <returns></returns>
IEnumerator Start()
{
string path = @"file:///F:\經典學習案例,忘記了可以回頭看的案例\siki的AssetBundle\AssetBundleProject\AssetBundles\scene\cubewall.unity3d";
//string path = @"http://localhost/AssetBundles\scene\cubewall.unity3d";
while (Caching.ready == false)
{
yield return null;
}
WWW www = WWW.LoadFromCacheOrDownload(path, 1);
yield return www;
if(string.IsNullOrEmpty(www.error)==false)
{
Debug.Log(www.error);
yield break;
}
AssetBundle ab = www.assetBundle;
//使用裏面的資源
var wallPrefab = ab.LoadAsset<GameObject>("cubeWall");
Instantiate(wallPrefab);
}
16-搭建簡單的Server服務器
使用NetBox2.exe可以方便把本文件夾做成網站
使用記事本創建首頁index.html
17-從服務器下載AssetBundle
使用www和UnityWebRequest都可以
18-使用UnityWebRequest下載AssetBundle
IEnumerator Start()
{
string uri = @"file:///F:\經典學習案例,忘記了可以回頭看的案例\siki的AssetBundle\AssetBundleProject\AssetBundles\scene\cubewall.unity3d";
UnityWebRequest request = UnityWebRequest.GetAssetBundle(uri);
yield return request.Send();
//AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
//使用裏面的資源
var wallPrefab = ab.LoadAsset<GameObject>("cubeWall");
Instantiate(wallPrefab);
}
19-從AssetBundle裏面加載資源
一般
T objectFromBundle = bundleObject.LoadAsset<T>(assetName);
GameObject
GameObject gameObject =
loadedAssetBundle.LoadAsset<GameObject>(assetName);
所有資源
Unity.Object[] objectArray =
loadedAssetBundle.LoadAllAssets();
20-通過Manifest文件得到某個包的依賴
加載Manifests文件可以處理資源的依賴
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dependencies = manifest.GetAllDependencies("assetBundle"); //Pass the name of the bundle you want the dependencies for.
foreach(string dependency in dependencies)
{
AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency));
}
AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//foreach (var item in manifest.GetAllDependencies("cube.unity3d"))
//{
// print(name);
//}
string[] strs = manifest.GetAllDependencies("cube.unity3d");
foreach (string name in strs)
{
print(name);
AssetBundle.LoadFromFile("AssetBundles/" + name);
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadFromFileExample : MonoBehaviour {
private void Start()
{
AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//foreach (var item in manifest.GetAllDependencies("cube.unity3d"))
//{
// print(name);
//}
string[] strs = manifest.GetAllDependencies("scene/cap.unity3d");
foreach (string name in strs)
{
print(name);
AssetBundle.LoadFromFile("AssetBundles/" + name);
}
}
}
21-AssetBundle的卸載
卸載有兩個方面
1,減少內存使用
2,有可能導致丟失
所以什麽時候去卸載資源
AssetBundle.Unload(true)卸載所有資源,即使有資源被使用著
(1,在關切切換、場景切換2,資源沒被用的時候 調用)
AssetBundle.Unload(false)卸載所有沒用被使用的資源
個別資源怎麽卸載1,通過 Resources.UnloadUnusedAssets. 2,場景切換的時候
22-關於文件校驗
CRC MD5 SHA1
相同點:
CRC、MD5、SHA1都是通過對數據進行計算,來生成一個校驗值,該校驗值用來校驗數據的完整性。
不同點:
1. 算法不同。CRC采用多項式除法,MD5和SHA1使用的是替換、輪轉等方法;
2. 校驗值的長度不同。CRC校驗位的長度跟其多項式有關系,一般為16位或32位;MD5是16個字節(128位);SHA1是20個字節(160位);
3. 校驗值的稱呼不同。CRC一般叫做CRC值;MD5和SHA1一般叫做哈希值(Hash)或散列值;
4. 安全性不同。這裏的安全性是指檢錯的能力,即數據的錯誤能通過校驗位檢測出來。CRC的安全性跟多項式有很大關系,相對於MD5和SHA1要弱很多;MD5的安全性很高,不過大概在04年的時候被山東大學的王小雲破解了;SHA1的安全性最高。
5. 效率不同,CRC的計算效率很高;MD5和SHA1比較慢。
6. 用途不同。CRC一般用作通信數據的校驗;MD5和SHA1用於安全(Security)領域,比如文件校驗、數字簽名等。
23-AssetBundle使用的一些問題
Patching with AssetBundles(打補丁)
1,依賴包重復問題
a,把需要共享的資源打包到一起
b,分割包,這些包不是在同一時間使用的
c,把共享部分打包成一個單獨的包
2,圖集重復問題
3,Android貼圖問題
4,iOS文件處理重復fixed in Unity 5.3.2p2.
24-AssetBundles瀏覽工具
GitHub上面的一個工具https://github.com/Unity-Technologies/AssetBundles-Browser
StreamingAssets文件夾裏面的東西會被全部打包(放聲音、圖片)
也把遊戲中AssetBundle文件放到這個文件夾裏面
工具裏面也有一個buildAssetBundle的方法,不用自己寫了
----》》Window-AssetBundle Browser
一、AssetBundle入門到掌握