unity使用AssetBundle使用记录一(续)--场景打包成AssetBundle并加载

前文“unity使用AssetBundle使用记录一--打包”中所说的打包是指的普通资源的打包,本文说的是场景打包成AssetBundle,然后加载出来。

场景打包成AssetBundle资源和普通资源打包有所区别。这时,需要通过Application.LoadLevel等接口来加载场景。用到的接口如下:

  1. Application.LoadLevel();  该接口可以通过名字或索引载入AssetBundle文件中包含的对应场景。当加载新场景时,所有之前加载的GameObject都被销毁。该接口已弃用,被SceneManager.LoadScene()代替了。
  2. Application.LoadLevelAsync(); 该接口和Application.LoadLevel()作用相同,不同的是该接口是对场景进行异步加载。已弃用,被SceneManager.LoadSceneAsync()代替。
  3. Application.LoadLevelAdditive(); 该接口不同于Application.LoadLevel()的是,加载场景不会销毁之前加载的GameObject。该接口已弃用,被SceneManager.LoadScene()(重载的函数,第二个参数决定了是否销毁之前加载的GameObject代替了。
  4. Application.LoadLevelAdditiveAsync();Application.LoadLevelAdditive()不同的是,该接口是异步加载。已弃用,被SceneManager.LoadSceneAsync()(重载的函数,第二个参数决定了是否销毁之前加载的GameObject)代替。

以下是打包场景时用到的两种方式的代码:(测试都能正确打包)

首先获得鼠标选中文件的代码:

//得到鼠标选中的文件,只返回文件名及后缀
static public string[] GetSelectionFile()
    {
        //SelectionMode.Unfiltered          返回整个选择。
        //SelectionMode.TopLevel            仅返回最顶层选择的变换;其他选择的子对象将被过滤出。
        //SelectionMode.Deep                返回选择和所有选择的子变换。
        //SelectionMode.ExcludePrefab       从选择中排除任何预制。
        //SelectionMode.Editable            排除任何对象不得修改。
        //SelectionMode.Assets              仅返回资源目录中的资源对象。
        //SelectionMode.DeepAssets          如果选择包含文件夹,也包含所有资源和子目录。
        //SelectionMode.OnlyUserModifiable  仅用户可修改??
        UnityEngine.Object[] arr = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.TopLevel);

        string[] str = new string[arr.Length];
        for (int i = 0; i < arr.Length; ++i)
        {
            string s = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf('/')) + "/" + AssetDatabase.GetAssetPath(arr[i]);
            Debug.Log(s);
            str[i] = s.Substring(s.LastIndexOf('/') + 1, s.Length - s.LastIndexOf('/') - 1);
            Debug.Log(str[i]);
        }

        return str;
    }

测试代码:

//打包场景为AssetBundle,使用BuildStreamedSceneAssetBundle方式
static void CreateSceneAssetBundle_BuildStreamedSceneAssetBundle()
    {
        string[] name = GetSelectionFile();
        for (int i = 0; i < name.Length; ++i)
        {
            string name2 = Application.dataPath + "/StreamingAssets/" + name[i].Substring(0, name[i].LastIndexOf('.')); //将要生成AssetBundle资源的路径及名称
            name[0] = Application.dataPath + "/Resources/" + name[0]; //场景文件路径及名称
            BuildPipeline.BuildStreamedSceneAssetBundle(name, name2, BuildTarget.Android); //官方说法是已弃用,但是没找到替代的函数,好奇怪!
        }
    }
//打包场景为AssetBundle,使用BuildPlayer方式
    static void CreateSceneAssetBundle_BuildPlayer()
    {
        string[] name = GetSelectionFile();
        for (int i = 0; i < name.Length; ++i)
        {
            string name2 = Application.dataPath + "/StreamingAssets/" + name[i].Substring(0, name[i].LastIndexOf('.'));
            name[0] = Application.dataPath + "/Resources/" + name[0];
            //通过服务器用WWW下载方式,采用BuildOptions.BuildAdditionalStreamedScenes打包能正确下载并加载。
            //使用None不能,能获取文件流,但是AssetBundle报null,为什么?并且包大小差距很大,前者30多kb,后者30000多kb,万倍了!
            BuildPipeline.BuildPlayer(name, name2, BuildTarget.Android, BuildOptions.None);
            //BuildOptions.None                            执行特定的编译没有任何指定的设置或而外的任务。
            //BuildOptions.Development                     编译一个独立播放器开发版本。
            //BuildOptions.AutoRunPlayer                   运行内置播放器。
            //BuildOptions.ShowBuiltPlayer                 显示内置播放器。
            //BuildOptions.BuildAdditionalStreamedScenes   编译一个unity3d资源包,其中包括额外的流场景。
            //BuildOptions.AcceptExternalModifications...  不要覆盖播放器目录,但接受用户的修改。
            //BuildOptions.WebPlayerOfflineDeployment      同时拷贝UnityObject.js和网络播放器,所以它不会从互联网上下载。
            //BuildOptions.ConnectWithProfiler             在编辑器启动带有连接到分析器的播放器。
            //BuildOptions.AllowDebugging                  允许脚本调试器附加到远程播放器。
            //BuildOptions.SymlinkLibraries                当生成iOS XCode项目时,符号连接运行时库。(更快的迭代时间)。
        }
    }

以下是测试加载用到的代码:(测试场景加载正确)

//场景文件名称
    public string sceneAssetBundle;
    //场景名称
    public string sceneName;
    
    IEnumerator Start()
    {
        string path = "file://" + Application.dataPath + "/Resources/" + sceneAssetBundle;
        WWW www = WWW.LoadFromCacheOrDownload(path, 0);
        yield return www;

        if (www.error == null)
        {
            //下面一行的对象ab貌似没用到,但是不写的话,会报错如下:
            //Scene 'sceneAssetBundleTest'(-1) couldn't be loaded because it has not been added to the build settings or the AssetBundle has not been loaded.
            //To add a scene to the build settings use the menu File->Build Settings...
            //UnityEngine.SceneManagement.SceneManager:LoadSceneAsync(String)
            //场景没加到Build Settings的场景列表中或AssetBundle未加载。
            AssetBundle ab = www.assetBundle; //将场景通过AssetBundle方式加载到内存中
            
            //Application.LoadLevelAsync(sceneName); 弃用的
            AsyncOperation asy = SceneManager.LoadSceneAsync(sceneName); //sceneName不能加后缀,只是场景名称
            yield return asy;
        }
        else
        {
            Debug.LogError(www.error);
        }
	}

你可能感兴趣的:(unity使用AssetBundle使用记录一(续)--场景打包成AssetBundle并加载)