Related Posts Plugin for WordPress, Blogger...

6-28 Introduction To AssetBundle

本章要開始進入AssetBundle的教學了。由於遊戲中的場景資源容易占用許多容量,導致我們輸出成Android, iOS的安裝包時的容量過大,所以我們可以將資源額外打包為資源包,節省安裝包的容量。待玩家開啟遊戲後再從Server下載資源包,這種做法在遊戲更新的時候也非常方便,僅更新資源的話就不需要重新上架安裝包,更新資源包即可。

建議從Untiy官方文檔中了解AssetBundle的相關資訊,我下面也會提供翻譯給大家參考。
https://docs.unity3d.com/Manual/AssetBundlesIntro.html

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

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

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


An AssetBundle is an archive file containing platform specific Assets (Models, Textures, Prefabs, Audio clips, and even entire Scenes) that can be loaded at runtime. AssetBundles can express dependencies between each other; e.g. a material in AssetBundle A can reference a texture in AssetBundle B. For efficient delivery over networks, AssetBundles can be compressed with a choice of built-in algorithms depending on use case requirements (LZMA and LZ4).

AssetBundles can be useful for downloadable content (DLC), reducing initial install size, loading assets optimized for the end-user’s platform, and reduce runtime memory pressure.

1. AssetBundle是一個壓縮包,包含模型、材質、Prefab、音效、整個場景,可以在遊戲運行的時候載入。
2. AssetBundle有著互相依賴的關係。
3. AssetBundle可以使用LZMA、LZ4的壓縮演算法,減少資源包大小,增加網路傳輸的速度。
4. AssetBundles用於可下載內容(DLC),減少安裝包大小,針對行動平台下載優化後的資源,可減少運行時的內存壓力。

What’s in an AssetBundle?

First is the actual file on disk. This we call the AssetBundle archive, or just archive for short in this document. The archive can be thought of as a container, like a folder, that holds additional files inside of it. These additional files consist of two types; the serialized file and resource files. The serialized file contains your assets broken out into their individual objects and written out to this single file. The resource files are just chunks of binary data stored separately for certain assets (textures and audio) to allow us to load them from disk on another thread efficiently.

Second is the actual AssetBundle object you interact with via code to load assets from a specific archive. This object contains a map of all the file paths of the assets you added to this archive to the objects that belong to that asset that need to be loaded when you ask for it.

1. 他是存在於硬碟上的文件,可以稱為一個壓縮包。壓縮包內包含有資料夾、各種檔案,主要分為兩種類:Serialized File、Resource File。
2. Serialized File:可序列化文件,資源會被打碎後統一放入一個單一文件中。
3. Resource File:資源文件,比如聲音、圖片材質會被單獨保存,方便快速加載。
4. 我們可以通過代碼從特定的AssetBundle中,加載所有我們當初加入到AssetBundle中的內容。

AssetBundle Workflow

Assigning Assets to AssetBundles

Build the AssetBundles

Upload AssetBundles to off-site storage

Loading AssetBundles and Assets


AssetBundle使用流程:
1. 指定資源的AssetBundles屬性
2. 建立AssetBundles
3. 上傳AssetBundles到其他服務器
4. 載入AssetBundles與內部資源

首先第一步,我們先在Project視窗選擇資源。

然後在Insepctor視窗中,右下角可見有一個AssetBundle選項,選擇New....

然後輸入我們想要的名稱,如這邊我輸入『trees』,後綴名輸入『Neko』。後綴名就像是副檔名一樣,這邊可以隨意輸入你想要的名稱,想要用來當作模型版本亦可,如v1, v2, v3。

這樣屬性就設定好了,接著讓我們來撰寫程式碼。新增一個Script文件名為CreateAssetBundles.cs,記得要放在Editor資料夾中。

CreateAssetBundles.cs程式碼如下:

using UnityEditor;
using System.IO;

public class CreateAssetBundles {

 [MenuItem("Assets/Build All AssetBundle/Android")]
 static void BuildAllAssetBundles(){
  string buildPath = "AssetBundle";
  if (!Directory.Exists (buildPath)) {
   Directory.CreateDirectory (buildPath);
  }
  BuildPipeline.BuildAssetBundles (buildPath, BuildAssetBundleOptions.None, BuildTarget.Android);
 }

}


撰寫好以後,就可以在選單中看見選項,Assets/Build All AssetBundle/Android。

然後等待建立完成,回到專案目錄資料夾,可見出現了一個新資料夾名為『AssetBundle』。

打開來以後,就會發現多了一些檔案,其中trees.neko就是我們剛才建立的AssetBundle。大家可能還會注意到有一些額外的文件,跟manifest文件,這個檔案的作用會於後續的文章再做介紹。
接著我再選擇更多模型,指定為AssetBundle,然後這邊的指定方式為『scene/medivaltown』,這樣產生出來的AssetBundle會被放在scene資料夾中。


如下圖為放在scene資料夾中的medievaltown.neko與trees.neko。

接著要來撰寫讀取AssetBundle的程式碼,這邊我們先跳過『上傳、下載』的步驟,直接從文件夾中讀取AssetBundle。首先,在場景中創建一個Empty GameObject,我取名為Building_a,然後新增一個Script名為LoadAssetBundle.cs。

LoadAssetBundle.cs的程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadAssetBundle : MonoBehaviour {

 [SerializeField] string loadPath;
 [SerializeField] string assetName;
 [SerializeField] Transform assetTransform;

 void Start () {
  // 加載AssetBundle
  AssetBundle assetBundle = AssetBundle.LoadFromFile(loadPath);
  // 從AssetBundle取得想要的資源
  GameObject Building_a = assetBundle.LoadAsset(assetName);
  // 產生資源
  Instantiate(Building_a, assetTransform.position, assetTransform.rotation);
 }

}


Building_a的設定如下,Load Path起始於專案的根目錄,Asset Name等於Prefab的名稱,Asset Transform用來設定模型的Position與Rotation,可以將Building_a自己的Transform拉進去。


執行遊戲前看一下,場景中空無一物。


執行遊戲後發現,場景中出現了一棟房子,不過好像有點問題?

 重新調整Building_a的Rotation。

重新執行遊戲,看起來正常多了。




留言