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


讀取/加載 AssetBundle 資源的多種方式


本文提供全流程,中文翻譯。

Chinar 堅持將簡單的生活方式,帶給世人!

(擁有更好的閱讀體驗 —— 高分辨率用戶請根據需求調整網頁縮放比例)



Chinar —— 心分享、心創新!

助力快速理解如何讀取 AssetBundle 中的資源

為新手節省寶貴的時間,避免采坑!


Chinar 教程效果:
這里寫圖片描述



全文高清圖片,點擊即可放大觀看 (很多人竟然不知道)


0

AssetBundle Description —— AssetBundle描述


AssetBundle 的具體定義網上諸多大神的解釋很是細致,一搜一大片,在這里我都不再班門弄斧了

這里 Chinar 只簡單說下為什么要用它
1. 如果所有的資源文件,全部打包到程序中,那么程序的安裝包就會很大

AssetBundle 文件放在服務器上,用的時候再從服務器進行加載,所以這個包根本就不在程序當中
2. 那就是最主要的熱更新了
發布軟件后,開發者進行很小的一次更新,都需要重新打包發布

而對於用戶來說,需要重新下載進行安裝,無疑導致了用戶體驗不好。只要有更新,用戶就重新安裝程序

AssetBundle 技術,可以在用戶重裝軟件的情況下,做到更改程序中的一些資源,設置

開發者可以實時的完成更新,應用到所有用戶的客戶端上,非常方便

那么 AssetBundle 打包后的資源,如何進行讀取呢?

由於 AssetBundle 打包后的文件,是外部文件,我們的程序又是如何加載其中的資源的呢?

這里 Chinar 具體介紹 4 AssetBundle 文件的讀取方式
舉個栗子黑白88
不知道如何打包AssetBundle資源的? (請點擊這里,了解打包流程)


1

Async Loading —— 內存加載-異步加載


從內存中加載

主要函數:AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path1))

我們如何將一個需要的資源打包到 AssetBundle 中呢?

為了便於測試我們是否加載了包中的資源內容,簡單的創建了一個 UI Image 來展示效果

Hierarchy 層次面板結構如下
舉個栗子黑白88
這里寫圖片描述
腳本如下:

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 賦值
    }
}

運行后效果:
這里寫圖片描述


2

Sync Loading —— 內存加載-同步加載(無需協成)


從內存中加載

這種加載方式,無需使用協成,即可直接完成資源的加載

主要函數:AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))
舉個栗子黑白88
腳本如下:

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 賦值
    }
}

運行后效果:
這里寫圖片描述


3

LoadFromFile ——本地加載


第二種加載方式,從本地加載資源

主要函數:AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))
舉個栗子黑白88
腳本如下:

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 賦值
    }
}

運行后效果:與上邊一致
這里寫圖片描述


4

LoadFromWWW ——本地/服務器加載


第三種加載方式,從本地 / 服務器 WWW 加載資源

主要函數:AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))

注意:Chinar為沒有服務器的朋友准備了測試資源

資源地址就在腳本中,注釋寫的很詳細。如果連接不上,可能是網絡問題,多連接幾次即可

想要幾百元就擁有自己的網站和服務器的話

請看最下方的服務器購買教程(不要忘記我的推廣券哦,可以減錢抽獎!
舉個栗子黑白88
腳本如下:

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



}

運行后效果:與上邊一致。但有些網絡連接慢的時候,資源需要等待下載才顯示
這里寫圖片描述


5

LoadWebServer ——從服務器網絡加載


第四種加載方式,從服務器/網絡上 Url 加載資源

注意:Chinar為沒有服務器的朋友准備了測試資源

資源地址就在腳本中,注釋寫的很詳細。如果連接不上,可能是網絡問題,多連接幾次即可

想要幾百元就擁有自己的網站和服務器的話

請看最下方的服務器購買教程(不要忘記我的推廣券哦,可以減錢抽獎!
舉個栗子黑白88
腳本如下:

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; //另一種寫法
    }
}

運行后效果:有些網絡連接慢的時候,資源需要等待下載才顯示
這里寫圖片描述


支持

May Be —— 搞開發,總有一天要做的事!


擁有自己的服務器,無需再找攻略!

Chinar 提供一站式教程,閉眼式創建!

為新手節省寶貴時間,避免采坑!


先點擊領取 —— 阿里全產品優惠券 (享受最低優惠)


1 —— 雲服務器超全購買流程 (新手必備!)

2 —— 阿里ECS雲服務器自定義配置 - 購買教程(新手必備!)

3—— Windows 服務器配置、運行、建站一條龍 !

4 —— Linux 服務器配置、運行、建站一條龍 !





技術交流群:806091680 ! Chinar 歡迎你的加入


END

本博客為非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究

對於需要復制、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯系,留言,Email: ichinar@icloud.com

對於經本博主明確授權和許可使用文章及內容的,使用時請注明文章或內容出處並注明網址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM