讀取/加載 AssetBundle 資源的多種方式
本文提供全流程,中文翻譯。 Chinar 堅持将簡單的生活方式,帶給世人! (擁有更好的閱讀體驗 —— 高分辨率使用者請根據需求調整網頁縮放比例) |
Chinar —— 心分享、心創新! 助力快速了解如何讀取 AssetBundle 中的資源 為新手節省寶貴的時間,避免采坑! |
Chinar 教程效果:
全文高清圖檔,點選即可放大觀看 (很多人竟然不知道)
AssetBundle 的具體定義網上諸多大神的解釋很是細緻,一搜一大片,在這裡我都不再班門弄斧了
這裡 Chinar 隻簡單說下為什麼要用它 |
---|
1. 如果所有的資源檔案,全部打包到程式中,那麼程式的安裝包就會很大 AssetBundle 檔案放在伺服器上,用的時候再從伺服器進行加載,是以這個包根本就不在程式當中 |
2. 那就是最主要的熱更新了 |
釋出軟體後,開發者進行很小的一次更新,都需要重新打包釋出 而對于使用者來說,需要重新下載下傳進行安裝,無疑導緻了使用者體驗不好。隻要有更新,使用者就重新安裝程式 AssetBundle 技術,可以在使用者重裝軟體的情況下,做到更改程式中的一些資源,設定 開發者可以實時的完成更新,應用到所有使用者的用戶端上,非常友善 |
那麼 AssetBundle 打包後的資源,如何進行讀取呢?
由于 AssetBundle 打包後的檔案,是外部檔案,我們的程式又是如何加載其中的資源的呢?
這裡 Chinar 具體介紹 4 種 AssetBundle 檔案的讀取方式
不知道如何打包AssetBundle資源的? (請點選這裡,了解打包流程)從記憶體中加載
主要函數:
AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path1))
我們如何将一個需要的資源打包到 AssetBundle 中呢?
為了便于測試我們是否加載了包中的資源内容,簡單的建立了一個 UI Image 來展示效果
Hierarchy 層次面闆結構如下
腳本如下:
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 異步加載 —— 從記憶體中加載 LoadFromMemory
/// </summary>
public class ChinarAsyncLoading : MonoBehaviour
{
private Image image; //場景中建立一個 UI Image元素為了測試
IEnumerator Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //動态擷取UI上的元件
string path1 = "ChinarAssetBundles/globule.unity3d"; //資源包路徑
string path2 = "ChinarAssetBundles/chinar/sprite.unity3d"; //子選項精靈圖檔檔案路徑
AssetBundleCreateRequest request1 = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path1)); //讀取檔案1請求
yield return request1; //傳回1
AssetBundleCreateRequest request2 = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path2)); //讀取檔案2請求
yield return request2; //傳回2
AssetBundle ab1 = request1.assetBundle; //資源1
AssetBundle ab2 = request2.assetBundle; //資源2
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加載ab1包中的資源名為 Sphere-Head 檔案的資料,傳回Object對象 (這是一個預設物)
Instantiate((GameObject) sphereHead); //将對象,轉為GameObject,執行個體化到場景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加載ab2包中的資源名為 Chianr1 檔案的資料,并轉為 Sprite類型,傳回Object對象 (這是精靈圖檔)
image.sprite = (Sprite) sprite; //轉為Sprite類型,給Image 指派
}
}
運作後效果:
這種加載方式,無需使用協成,即可直接完成資源的加載
AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))
using System.IO;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 同步加載 —— 無需協成,從記憶體加載
/// </summary>
public class ChinarSyncLoading : MonoBehaviour
{
private Image image; //場景中建立一個 UI Image元素為了測試
void Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //動态擷取UI上的元件
string path1 = "ChinarAssetBundles/globule.unity3d"; //資源包路徑
string path2 = "ChinarAssetBundles/chinar/sprite.unity3d"; //子選項精靈圖檔檔案路徑
AssetBundle ab1 = AssetBundle.LoadFromMemory(File.ReadAllBytes(path1)); //資源1
AssetBundle ab2 = AssetBundle.LoadFromMemory(File.ReadAllBytes(path2)); //資源2
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加載ab1包中的資源名為 Sphere-Head 檔案的資料,傳回Object對象 (這是一個預設物)
Instantiate((GameObject) sphereHead); //将對象,轉為GameObject,執行個體化到場景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加載ab2包中的資源名為 Chianr1 檔案的資料,并轉為 Sprite類型,傳回Object對象 (這是精靈圖檔)
image.sprite = (Sprite) sprite; //轉為Sprite類型,給Image 指派
}
}
第二種加載方式,從本地加載資源
AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 同步加載 —— 無需協成,從本地加載
/// </summary>
public class ChinarFileLoading : MonoBehaviour
{
private Image image; //場景中建立一個 UI Image元素為了測試
void Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //動态擷取UI上的元件
string path1 = "ChinarAssetBundles/globule.unity3d"; //資源包路徑
string path2 = "ChinarAssetBundles/chinar/sprite.unity3d"; //子選項精靈圖檔檔案路徑
AssetBundle ab1 = AssetBundle.LoadFromFile(path1); //資源1:直接讀出資源
AssetBundle ab2 = AssetBundle.LoadFromFile(path2); //資源2:直接讀出資源
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加載ab1包中的資源名為 Sphere-Head 檔案的資料,傳回Object對象 (這是一個預設物)
Instantiate((GameObject) sphereHead); //将對象,轉為GameObject,執行個體化到場景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加載ab2包中的資源名為 Chianr1 檔案的資料,并轉為 Sprite類型,傳回Object對象 (這是精靈圖檔)
image.sprite = (Sprite) sprite; //轉為Sprite類型,給Image 指派
}
}
運作後效果:與上邊一緻
第三種加載方式,從本地 / 伺服器 WWW 加載資源
AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))
注意:Chinar為沒有伺服器的朋友準備了測試資源
資源位址就在腳本中,注釋寫的很詳細。如果連接配接不上,可能是網絡問題,多連接配接幾次即可
想要幾百元就擁有自己的網站和伺服器的話
請看最下方的伺服器購買教程(不要忘記我的推廣券哦,可以減錢抽獎!
using System.Collections;
using System.Security.Policy;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 網絡伺服器加載方式
/// </summary>
public class ChinarWwwLoading : MonoBehaviour
{
private Image image; //場景中建立一個 UI Image元素為了測試
IEnumerator Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //動态擷取UI上的元件
string path1 = "file:C:/Users/Administrator/Desktop/Tutorial AssetBundle/ChinarAssetBundles/globule.unity3d"; //本地資源包路徑
string path2 = "http://www.unity.kim/ChinarAssetBundles/chinar/sprite.unity3d"; //伺服器上,存放的子選項精靈圖檔檔案網絡位址
while (Caching.ready == false) yield return null; //是否準備好
WWW www1 = WWW.LoadFromCacheOrDownload(@path1, 1); //從本地加載
WWW www2 = WWW.LoadFromCacheOrDownload(@path2, 1); //從伺服器加載
yield return www2; //等待伺服器加載完成,再向下執行
if (string.IsNullOrEmpty(www2.error) == false) //報空傳回
{
Debug.Log(www2.error);
yield break;
}
AssetBundle ab1 = www1.assetBundle; //本地,資源包1,其中為預設物
AssetBundle ab2 = www2.assetBundle; //網絡,資源包2,其中為Chinar上傳好的圖檔,大家可以放心加載測試
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加載ab1包中的資源名為 Sphere-Head 檔案的資料,傳回Object對象 (這是一個預設物)
Instantiate((GameObject)sphereHead); //将對象,轉為GameObject,執行個體化到場景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加載ab2包中的資源名為 Chianr1 檔案的資料,并轉為 Sprite類型,傳回Object對象 (這是精靈圖檔)
image.sprite = (Sprite)sprite; //轉為Sprite類型,給Image 指派
}
//#region 第二種網絡加載方式
//IEnumerator Start()
//{
// image = GameObject.Find("Image").GetComponent<Image>();
// string path1 = "file:C:/Users/Administrator/Desktop/Tutorial AssetBundle/ChinarAssetBundles/globule.unity3d"; //本地預設物資源包路徑
// //(Chinar為沒有自己伺服器的準備的以下網絡資源,直接加載即可)
// //如果想買個伺服器,請看Chinar伺服器購買教程,非常簡便便宜(記得領券哦)
// string path2 = "http://www.unity.kim/ChinarAssetBundles/globule.unity3d"; //伺服器上,存放的預設物路徑(Chinar為沒有自己伺服器的準備的資源,直接加載即可)
// string path3 = "http://www.unity.kim/ChinarAssetBundles/chinar/sprite.unity3d"; //伺服器上,存放的子選項精靈圖檔檔案網絡位址
// using (WWW www = new WWW(path3))
// {
// yield return www; //等待網絡下載下傳
// if (www.error != null) //如果錯誤資訊不為空
// {
// print("網絡錯誤"); //提示網絡錯誤
// }
// else
// {
// AssetBundle bundle = www.assetBundle; //聲明 bundle對象接收資源
// #region 1-網絡預設物資源加載,執行個體化
// //object obj = bundle.LoadAsset("Sphere-Head"); //加載資源 傳回一個Object對象 指派給obj
// //Instantiate((GameObject)obj);
// #endregion
// #region 2-網絡精靈圖檔1資源加載,執行個體化
// //object obj = bundle.LoadAsset(""Chinar1"", typeof(Sprite)); //加載資源 傳回一個Object對象,轉Sprite 指派給obj
// //image.sprite = (Sprite)obj;
// #endregion
// #region 3-網絡精靈圖檔2資源加載,執行個體化
// object obj = bundle.LoadAsset("Chinar青色", typeof(Sprite)); //加載資源 傳回一個Object對象,轉Sprite 指派給obj
// image.sprite = (Sprite)obj;
// print(obj);
// #endregion
// bundle.Unload(false); //隻解除安裝已經用過的
// }
// www.Dispose(); //釋放資源
// }
//}
//#endregion
}
運作後效果:與上邊一緻。但有些網絡連接配接慢的時候,資源需要等待下載下傳才顯示
第四種加載方式,從伺服器/網絡上 Url 加載資源
注意:Chinar為沒有伺服器的朋友準備了測試資源
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
/// <summary>
/// Unity 新網絡伺服器加載AssetBundle方式
/// </summary>
public class ChinarWebServerLoading : MonoBehaviour
{
private Image image; //場景中建立一個 UI Image元素為了測試
IEnumerator Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //動态擷取UI上的元件
const string url1 = @"http://www.unity.kim/ChinarAssetBundles/globule.unity3d"; //伺服器位址,Chinar提供用于測試,大神勿黑!(存一個預設物:"Sphere-Head")
const string url2 = @"http://www.unity.kim/ChinarAssetBundles/chinar/sprite.unity3d"; //伺服器上,存放的子選項精靈圖檔檔案網絡位址(存2張Sprite:"Chinar1"與“Chinar青色”)
UnityWebRequest request1 = UnityWebRequestAssetBundle.GetAssetBundle(url1); //Unity網絡請求AssetBundle.擷取資源(網絡位址1)
UnityWebRequest request2 = UnityWebRequestAssetBundle.GetAssetBundle(url2); //傳入位址2
yield return request1.SendWebRequest(); //發送Web請求1
yield return request2.SendWebRequest(); //發送web請求2
AssetBundle ab1 = DownloadHandlerAssetBundle.GetContent(request1); //下載下傳資源委托,擷取連接配接請求1,傳回AssetBundle資源
AssetBundle ab2 = DownloadHandlerAssetBundle.GetContent(request2); //擷取連接配接請求2,傳回AssetBundle資源
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加載 資源ab1中的名叫“Sphere-Head”的圓球
Instantiate((GameObject) sphereHead); //執行個體化出來
object obj = ab2.LoadAsset("Chinar青色", typeof(Sprite)); //加載資源 傳回一個Object對象,轉Sprite 指派給obj
image.sprite = (Sprite) obj; //指派給UiImage
//AssetBundle ab = ((DownloadHandlerAssetBundle)request3.downloadHandler).assetBundle; //另一種寫法
}
}
運作後效果:有些網絡連接配接慢的時候,資源需要等待下載下傳才顯示
擁有自己的伺服器,無需再找攻略! Chinar 提供一站式教程,閉眼式建立! 為新手節省寶貴時間,避免采坑! |
1 ——
雲伺服器超全購買流程 (新手必備!)2 ——
阿裡ECS雲伺服器自定義配置 - 購買教程(新手必備!)3——
Windows 伺服器配置、運作、建站一條龍 !4 ——
Linux 伺服器配置、運作、建站一條龍 !技術交流群:806091680 ! Chinar 歡迎你的加入
END
本部落格為非營利性個人原創,除部分有明确署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究
對于需要複制、轉載、連結和傳播部落格文章或内容的,請及時和本部落客進行聯系,留言,Email: [email protected]
對于經本部落客明确授權和許可使用文章及内容的,使用時請注明文章或内容出處并注明網址