场景跳转是游戏里面不可缺少的内容, 这里写写我这个小白遇到的问题.
场景资源比较大, 同步切换场景不现实. 场景一般比较多, 都加到 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
- }
- }
这里没有写进度条相关的功能, 大家可以自行解决.
来源: https://www.cnblogs.com/lihangppz/p/10434245.html