目的:把 場景 打包成 .unity3d 檔案, 再動態載入, 使用場景.
* Scene 的打包方式一:
string[] unityList = new string[] {
"Assets/xxx1.unity",
"Assets/xxx2.unity",
};
string targetPath = System.IO.Directory.GetParent (Application.dataPath).ToString () + "/_output/";
string targetFileName = targetPath + "xxx.unity3d";
BuildPipeline.BuildPlayer (unityList, targetFileName, BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes);
"Assets/xxx1.unity",
"Assets/xxx2.unity",
};
string targetPath = System.IO.Directory.GetParent (Application.dataPath).ToString () + "/_output/";
string targetFileName = targetPath + "xxx.unity3d";
BuildPipeline.BuildPlayer (unityList, targetFileName, BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes);
* Scene 的打包方式二:
string[] unityList = new string[] {
"Assets/xxx1.unity",
"Assets/xxx1.unity",
"Assets/xxx2.unity",
};
string targetPath = System.IO.Directory.GetParent (Application.dataPath).ToString () + "/_output/";
string targetFileName = targetPath + "xxx.unity3d";
BuildPipeline.BuildStreamedSceneAssetBundle (unityList, targetFileName, BuildTarget.WebPlayer);
};
string targetPath = System.IO.Directory.GetParent (Application.dataPath).ToString () + "/_output/";
string targetFileName = targetPath + "xxx.unity3d";
BuildPipeline.BuildStreamedSceneAssetBundle (unityList, targetFileName, BuildTarget.WebPlayer);
* 加載方式一:
輪詢下列函式, 直接它回覆 Status.loaded, 再進行 Application.LoadLevel
(可用 Application.CanStreamedLevelBeLoaded 檢查目標是否有載進來)
static public Status checkLoader (string fileName, ref WWW www, ref string errMsg)
{
errMsg = "";
if (www == null) {
string url = fileName;
if (Application.platform == RuntimePlatform.WindowsWebPlayer)
url = Application.dataPath + "/" + url + "?rr=" + (new System.Random ()).Next ().ToString ();
else if (Application.platform == RuntimePlatform.WindowsEditor)
url = "file:///" + System.IO.Directory.GetParent (Application.dataPath).ToString () + "/_output/" + url;
else if (Application.platform == RuntimePlatform.WindowsPlayer)
url = "file:///" + System.IO.Directory.GetParent (Application.dataPath).ToString () + "/" + url;
else {
errMsg = "未支援平台\n" + Application.platform + "\n" + Application.dataPath;
return Status.fail;
}
www = new WWW (url);
return Status.loading;
}
if (www.progress < 1) return Status.loading;
if (www.error != null) {
errMsg = "載入失敗:" + www.error;
return Status.fail;
}
if (www.assetBundle == null) {
errMsg = "載入失敗:內容是空的\n" + www.url;
return Status.fail;
}
string url = fileName;
if (Application.platform == RuntimePlatform.WindowsWebPlayer)
url = Application.dataPath + "/" + url + "?rr=" + (new System.Random ()).Next ().ToString ();
else if (Application.platform == RuntimePlatform.WindowsEditor)
url = "file:///" + System.IO.Directory.GetParent (Application.dataPath).ToString () + "/_output/" + url;
else if (Application.platform == RuntimePlatform.WindowsPlayer)
url = "file:///" + System.IO.Directory.GetParent (Application.dataPath).ToString () + "/" + url;
else {
errMsg = "未支援平台\n" + Application.platform + "\n" + Application.dataPath;
return Status.fail;
}
www = new WWW (url);
return Status.loading;
}
if (www.progress < 1) return Status.loading;
if (www.error != null) {
errMsg = "載入失敗:" + www.error;
return Status.fail;
}
if (www.assetBundle == null) {
errMsg = "載入失敗:內容是空的\n" + www.url;
return Status.fail;
}
return Status.loaded;
}
* 加載方式二:
和方式一相同,只是改用 yield 來處理 (它的功能是:再次呼叫該函式時, 不會從函式的開頭開始, 會直接跳到 yield 的地方接續下來)
個人不太愛用, 也還不太熟悉它, 雖有測試成功, 但在此不描述了.
* 注意事項:
- 載入的Scene存在assetBundle內, 但無法用Load之類的函式取得內容.
應改用 Application.CanStreamedLevelBeLoaded 判斷目標 Scene 是否存在, 用 LoadLevel 載入.
- 若 assetBundle 釋放掉 (Unload) 則該Scene也會被移除.
而且, 重新加載的話, 可以加載成功, 但 LoadLevel 似乎會被導到第一次加載時的 Scene 位址, 而該位址已被 Unload, 而呈現漆黑一片, 畫面當掉.
- 未找到讓LoadLevel忘記第一次加載的Scene的方法. 所以 assetBundle 必須保存, WWW 可移除.
AssetBundle assetBundle = www.assetBundle;
www.dispose();
www = null;
參考資料:
其他遺漏...
