1. 程式人生 > >Unity3D基礎學習之AssetBundle 資源包建立與載入

Unity3D基礎學習之AssetBundle 資源包建立與載入

前幾天做了AssentBundle的例子,遇到了問題,在論壇上問了三天都沒人解答,最後在一個朋友的幫助下解決了。下面介紹AssentBundle。

AssetBundles讓你通過WWW類流式載入額外的資源並在執行時例項化它們。AssetBundles通過BuildPipeline.BuildAssetBundle建立。

看了雨凇MOMO的關於 AssetBundles的帖子,受益很多,但是他把資源全達成.assetbundle 二進位制格式,與Unity幫助指令碼中不一樣,Unity幫助文件中打包和載入的檔案字尾名都是.unity3d格式,而且網上其他人也都用的.unity格式,所以我也就打成.unity3d格式。

打包AssentBundle:

最核心的方法其實就它:

BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)

不過這是預設的電腦上打包的資源只可以電腦上用

安卓打包需要新增引數:

BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets,BuildTarget.Android

);

Iphone打包也需要新增引數:
 BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets,BuildTarget.iPhone);

需要在專案檔案根目錄Assets下新建Editor資料夾,新建C#指令碼“ExportAssetBundles”。

using UnityEngine;
using System.Collections;
using UnityEditor;//必須引用此類

public class ExportAssetBundles : MonoBehaviour
{
    /// <summary>
    /// 將所選擇的的物體和物體有依賴關係的物件一起打包
    /// </summary>
    [MenuItem("Assets/Build AssetBundle From Selection - Track dependencies")]

    static void ExportResource()
    {
        // Bring up save panel

        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");

        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies |

BuildAssetBundleOptions.CompleteAssets);
            Selection.objects = selection;

        }

    }

    /// <summary>
    /// 只打包選擇的物體
    /// </summary>
    [MenuItem("Assets/Build AssetBundle From Selection - No dependency tracking")]

    static void ExportResourceNoTrack()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path);
        }
    }
}

儲存之後,選中專案中的檔案,滑鼠右鍵或者Assent選單下都會有這兩個選項,根據自己的需要打包即可。

下載AssentBundle:Assetbundle是可以同時放在伺服器或者本地的,無論放在哪裡兩種下載讀取的方式是完全一樣的。所以我建議在做unity專案的時候開始就把資源放在Assetbundle中在本地來做,等做的差不多了直接把Assetbundle放在伺服器上,因為兩種讀取的方式完全一樣,這樣以後更新資源會方便很多。 using UnityEngine;
using System.Collections;public class assentBuntleScript : MonoBehaviour
{   
    public static readonly string URL = http://"+"網址";網路路徑
    //public static readonly string URL = "file://" + Application.dataPath+"/mm.unity3d";//本地路徑    void OnGUI()
    {
        if(GUILayout.Button("下載資源"))
        {
            StartCoroutine(loadBundleOBject(URL));
        }
    }    IEnumerator loadBundleOBject(string url)
    {
        WWW date = new WWW(url);
        yield return date;
        Instantiate(date.assetBundle.mainAsset);//例項化載入的資源,我載入的是個模型。
        date.assetBundle.Unload(false);
    }
}

下載類WWW
WWW bundle = new WWW(path);
這樣的做法是通過一個路徑進行下載(無論是伺服器路徑還是本地路徑下載操作都一樣)但是bundle只能儲存在記憶體中,也就是退出遊戲在進入還得重新下,很顯然在遊戲中我們不能使用這種方式。
IEnumerator loadBundleOBject(string url)
    {
        WWW date = WWW.LoadFromCacheOrDownload(url,5);
        yield return date;
        Instantiate(date.assetBundle.mainAsset);//例項化載入的資源,我載入的是個模型。
        date.assetBundle.Unload(false);
    }
使用的方法是WWW.LoadFromCacheOrDownload(path,5);引數1:伺服器或者本地下載地址 引數2:版本號Unity會下載Assetbundle本地中,它的工作原理是先通過(版本號和下載地址)先在本地去找看有沒有這個Assetbundle,如果有直接返回物件,如果沒有的話,在根據這個下載地址重新從伺服器或者本地下載。這裡版本號起到了很重要的作用,舉個例子,同一下載地址版本號為1的時候已經下載到本地,此時將版本號的引數改成2 那麼它又會重新下載,如果還保持版本號為1那麼它會從本地讀取,因為本地已經有版本號為1的這個Assetbundle了。你不用擔心你的資源本地下載過多,也不用自己手動刪除他們,這一切的一切Unity會幫我們自動完成,它會自動刪除掉下載後最不常用的Assetbundle ,如果下次需要使用的話只要提供下載地址和版本後它會重新下載。(轉自雨鬆MOMO研究院)
        Assetbundle 中的指令碼,在移動平臺下Assetbundle裡面放的指令碼是不會被執行的,在手機上將Assetbundle下載到本地後,載入進遊戲中Prefab會自動在本地找它身上掛著的指令碼,他是根據指令碼的名來尋找,如果本地有這條指令碼的話,Prefab會把這個指令碼重新繫結在自身,並且會把打包前的引數傳遞進來。如果本地沒有,身上掛的條指令碼永遠都不會被執行。(轉自雨鬆MOMO研究院)

最後再說說我遇到的問題,本地載入.unity3d的資源沒問題,但是我掛到IIS上就失敗了,顯示404錯誤,找不到資源,無法例項化。這就需要配置伺服器的MIME了,因為伺服器不識別.unity3d格式的資源,所以伺服器不響應請求,所以就下不下來。
    這樣就行了,可以下載.unity3d,這就是困擾我三天的問題啊,怎麼都下載不了,最終是這麼個問題。