unity 簡易場景切換
場景跳轉是遊戲裏面不可缺少的內容,這裏寫寫我這個小白遇到的問題。
場景資源比較大,同步切換場景不現實。場景一般比較多,都加到scenes in build也不太現實。
這裏將初始場景和過渡場景加到scenes in build,一般而言是login和loading場景,將其他場景打成uab的包。
這裏忽略其他功能,單純來說場景跳轉。
場景同步跳轉SceneManager.LoadScene("loading", LoadSceneMode.Single);同步跳轉有個條件需要加到scenes in build。loading場景做成一個很小的場景,並且帶一個進度條。幾乎是瞬間就可以加載完成,同時異步加載目標場景,用SceneManager.LoadSceneAsync("targetSence", LoadSceneMode.Single);這裏也有條件,加到scenes in build,或者uab已被加載。
在loagin場景,也就是初始場景上,掛上下面腳本:
using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class MainStart : MonoBehaviour { void Start() { DontDestroyOnLoad(this); SceneManager.LoadScene("loading", LoadSceneMode.Single); StartCoroutine("LoadScene"); } //異步加載 IEnumerator LoadScene() { WWW download = new WWW("file:///" + Application.dataPath + "/target/targetSence.uab"); yield return download; Debug.Log(download.ToString()); AsyncOperation async = SceneManager.LoadSceneAsync("targetSence", LoadSceneMode.Single); yield return async; } }
資源打包部分就不細說了,代碼放到Editor下:
using UnityEditor; using UnityEngine; public class TestUab { [MenuItem("Assets/資源打包", false, 63)] public static void testUab() { string targetPath = Application.dataPath + "/target"; AssetBundleBuild abb = new AssetBundleBuild(); abb.assetBundleName = "targetSence.uab"; abb.assetNames = new string[1]; abb.assetNames[0] = "Assets/TestUab/" + "targetSence.unity"; AssetBundleBuild[] addArr = new AssetBundleBuild[1]; addArr[0] = abb; BuildPipeline.BuildAssetBundles(targetPath, addArr, BuildAssetBundleOptions.None, BuildTarget.Android); } }
將login,loading場景加入到scenes in build,並且打包目標場景後,開始運行,你會發現場景切換沒有問題了,但是天空盒變成紫色了。剛開始以為材質丟了,點開Lighting界面,材質沒丟,但是shader渲染出來的就是紫色。花了很長時間沒解決,然後翻自己的線上工程,發現線上工程沒有天空盒,一口老血噴到屏幕上了,最後還是請教老大,才知道問題。
在打uab包時,用的是Android平臺,BuildPipeline.BuildAssetBundles(targetPath, addArr, BuildAssetBundleOptions.None, BuildTarget.Android);所以打出來的uab包時Android平臺下的,shader都是Android平臺下的shader,不同平臺shader渲染不一樣。把dome工程打成apk,一看果然天空盒沒問題,沒有變成紫色。線上項目在場景加載完畢的時候會切換材質球的shader,以保證在編輯器下顯示沒有問題。最終代碼如下:
using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; public class MainStart : MonoBehaviour { // Use this for initialization void Start() { DontDestroyOnLoad(this); SceneManager.LoadScene("loading", LoadSceneMode.Single); StartCoroutine("LoadScene"); } //異步加載 IEnumerator LoadScene() { WWW download = new WWW("file:///" + Application.dataPath + "/target/targetSence.uab"); yield return download; Debug.Log(download.ToString()); AsyncOperation async = SceneManager.LoadSceneAsync("targetSence", LoadSceneMode.Single); yield return async; ChangeShader(); } //替換材質 private void ChangeShader() { #if UNITY_EDITOR //替換場景物體材質 Terrain terrain = GameObject.FindObjectOfType<Terrain>(); if (terrain != null) { terrain.materialType = Terrain.MaterialType.BuiltInLegacyDiffuse; } Object[] objs = GameObject.FindObjectsOfType(typeof(GameObject)); for (int k = 0; k < objs.Length; k++) { GameObject go = objs[k] as GameObject; Renderer[] componentsInChildren = go.GetComponents<Renderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] sharedMaterials = componentsInChildren[i].sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (sharedMaterials[j] != null) { Shader shader = sharedMaterials[j].shader; if (shader != null) { Shader shader2 = Shader.Find(shader.name); if (shader2 != null) { sharedMaterials[j].shader = shader2; } } } } } } //替換天空盒材質 Shader shader02 = RenderSettings.skybox.shader; RenderSettings.skybox.shader = Shader.Find(shader02.name); Debug.Log("替換材質"); #endif } }
這裏沒有寫進度條相關的功能,大家可以自行解決。
unity 簡易場景切換