您的位置:首页 > 移动开发 > Unity3D

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

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

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

Application.LoadLevel();  该接口可以通过名字或索引载入AssetBundle文件中包含的对应场景。当加载新场景时,所有之前加载的GameObject都被销毁。该接口已弃用,被SceneManager.LoadScene()代替了。
Application.LoadLevelAsync(); 该接口和Application.LoadLevel()作用相同,不同的是该接口是对场景进行异步加载。已弃用,被SceneManager.LoadSceneAsync()代替。
Application.LoadLevelAdditive(); 该接口不同于Application.LoadLevel()的是,加载场景不会销毁之前加载的GameObject。该接口已弃用,被SceneManager.LoadScene()(重载的函数,第二个参数决定了是否销毁之前加载的GameObject)代替了。
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(sc
4000
eneName); 弃用的
AsyncOperation asy = SceneManager.LoadSceneAsync(sceneName); //sceneName不能加后缀,只是场景名称
yield return asy;
}
else
{
Debug.LogError(www.error);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  assetbundle