天天看點

Unity讀取AssetBundle資源全教程(所有讀取方式)012345支援

讀取/加載 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]

對于經本部落客明确授權和許可使用文章及内容的,使用時請注明文章或内容出處并注明網址

繼續閱讀