1. 程式人生 > >unity 簡易場景切換

unity 簡易場景切換

工程 () soft 線上 遇到的問題 sof pan obj 材質

  場景跳轉是遊戲裏面不可缺少的內容,這裏寫寫我這個小白遇到的問題。

  場景資源比較大,同步切換場景不現實。場景一般比較多,都加到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 簡易場景切換