Unity 中場景切換


Unity游戲開發中,單個Scene解決所有問題似乎不可能,那么多個Scene之間的切換是必然存在。如果僅僅是切換,似乎什么都好說,但是在場景比較大的時候不想讓玩家等待加載或者說場景與場景之間想通過一些畫面、動畫表現出一些讓玩家期待的東西,大家就要去認真考慮。這篇文章主要介紹兩種增加切換中如何播放畫面或者動畫等等,提高玩家的浸入感,當然你也可以做成無縫的場景

1 操作基礎函數

LoadLevel Loads the level by its name or index. 
加載場景,加載之前你需要把場景在Build Settings添加,場景加載后,場景中的激活物體會調用MonoBehavior:OnLevelWasLoaded().使用該方法的時候,之前場景中的物體將會被直接刪除。
LoadLevelAdditive Loads a level additively.
該方法不銷毀當前場景中的物體,新場景中的物體將會被添加進來,這個方法在一些連續加載的場景中非常有用哈。
LoadLevelAdditiveAsync Loads the level additively and asynchronously in the background.
在后台異步記載場景
unity會在后台線程中加載所有的場景資源,這就允許你在加載新場景過程中播放一個進度條或者通過異步加載為玩家創造一個流程的世界
該方法會返回AsyncOperation結構,結構中isDone表示是否完成,progress給出當前的播放進度。注意的是在編輯器中后台線程的性能要低於游戲中。
LoadLevelAsync Loads the level asynchronously in the background.
在后台異步記載場景
unity會在后台線程中加載所有的場景資源,這就允許你在加載新場景過程中播放一個進度條或者通過異步加載為玩家創造一個流程的世界
該方法會返回AsyncOperation結構,結構中isDone表示是否完成,progress給出當前的播放進度。注意的是在編輯器中后台線程的性能要低於游戲中。
 

是否銷毀

LoadLevel和LoadLevelAsync,在加載完成后之后將會立刻銷毀原先場景中的物體,而LoadLevelAdditive和LoadLevelAdditiveAsync加載后將會保留原先的場景中的物體,這種方式可以實現無縫融合的場景,只需要你在適當的位置加載后面的場景,不過你還是要考慮資源的釋放問題。

同步還是異步

     異步加載能夠獲得加載過程的進度和是否加載完成,通過這種方式你可以在切換中增減進度條或者其他表現,這種方式一般通過協程完成:
public class ExampleClass : MonoBehaviour 
{
    IEnumerator Start() 
    {
        AsyncOperation async = Application.LoadLevelAsync("MyBigLevel");
        yield return async;
        Debug.Log("Loading complete");
    }
}
 
需要注意的是:在使用之前需要在Build Settings 添加Scene。
 

2 切換畫面實現方法

場景切換中實現畫面或者動畫的方式有很多種,我現在看到的主要有兩種,這里大致做下兩種方式:

第一種方式:增加新場景

增加新場景的方式可以參考雨松的博客:Unity3D研究院之異步加載游戲場景與異步加載游戲資源進度條(三十一),增加新場景的優點是增加了很多的靈活性,你在中間過渡場景中增加視頻播放、圖片或者是GUI,缺點就是如果你想在實現通用性,就需要頂層做一些數據輔助,比如加載前的場景中設置好切換時播放的圖片到頂層數據管理模塊中,在浸入切換場景后在獲取這些數據,根據這些數據來切換播放的動畫等等。

左圖為測試工程中三個場景,Pre為當前場景,Middle為切換場景,Next是需要加載的場景。右圖為middle場景中的存在的物體,掛有實現腳本。案例邏輯:Pre場景中直接進入middle場景,在middle場景中預先加載Next場景,確保新場景加載完之后不會立刻顯示Next的場景,而是等待用戶的觸摸或者點擊操作

                    3             4

具體的操作過程:

(1)在Pre場景中使用同步加載方法直接進入middle場景,因為Middle場景非常小,所以這個過程會非常快

Application.LoadLevel("Middle");

(2)Middle場景的邏輯

public class NewBehaviourScript2 : MonoBehaviour 
{
    public     Texture BackImage = null;
    private AsyncOperation async = null;
    void Start () 
    {
        //此物體在下一個場景中不會被銷毀
        DontDestroyOnLoad(this);

        //開始加載場景
        StartCoroutine("LoadScene");
    }
    
    //異步加載
    IEnumerator LoadScene()
    {
        async = Application.LoadLevelAsync("Next");
        yield return async;
        Debug.Log("Complete!");
    }

    void OnGUI()
    {
        //切換場景中的背景,可以是圖片或者動畫,或者~~
        GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), BackImage);

        //加載過程中顯示進度,也可以是進度條
        if (async != null && async.isDone == false)
        {
            GUIStyle style = new GUIStyle();
            style.fontSize = 48;
            GUI.Label(new Rect(0, 200, Screen.width, 20), async.progress.ToString("F2"), style);
        }

        //在加載結束后,彈出是否下個場景,模擬手游中"觸摸任意位置進入游戲"
        if (async != null && async.isDone == true)
        {
            if (GUI.Button(new Rect(100, 100, 100, 100), new GUIContent("跳起進入下一個場景")))
            {
                Destroy(this);
            }
        }


    }
}

A 場景中添加一個占滿全屏的背景圖,當然也可以使用動畫、視頻等,場景加載后馬上開始加載下一個場景(異步),根據異步加載進度進行進度條、動畫等等進度控制

B 注意:MiddleObj物體被設置為DontDestroyOnLoad(this),也就是在新的場景中不銷毀,即使在新場景加載后也會占滿全屏的背景仍然存在,直到物體被銷毀

C MiddleObj物體銷毀的方式有兩種,一種是手動方式,就像下面代碼中使用的,點擊Middle場景中的按鈕銷毀自己 ,另外一種自動方式是在新場景(Next場景)中的MonoBehavior:OnLevelWasLoaded()函數中銷毀該物體。

void OnLevelWasLoaded(int level)
   {
       GameObject obj = GameObject.Find("MiddleObj");
       if (obj != null)
       {
           GameObject.Destroy(obj);
       }
   }

 

雨松在實現新加載場景中先將場景中的所有物體隱藏,場景切換之后再慢慢的顯示出來,而不是通過DontDestroyOnLoad的方式,也是一種辦法哈。如果想要把這種方式設計為通用模式,可以增加一個數據管理器,在加載前提前設置好需要的圖片、動畫資源等內容,OK ,就可以在多個場合使用啦。

2

第二種方式使用prefab

這種方式和第一種方式原理上其實類似,只不過不使用新的場景,而是在Pre場景中增加類似於上面Middle場景中的MiddleObj物體中的邏輯,並且設置為DontDestroyOnLoad。這種方式中可以參考的就是SceneManager場景管理插件,SceneManager的使用可以參考:


     http://blog.csdn.net/onerain88/article/details/12303511

http://www.haogongju.net/art/2499058

5           6

具體使用我就不多說了哈,咱先看看其實現的關鍵原理:SceneManger使用異步加載新場景,進入加載之后,就會根據選擇使用不同的屏幕效果,並且這個效果是不會在新場景中消失的,直到需要的效果目標達到,就會顯出出先場景。SceneManger提供了一些列的屏幕效果Prefab以及場景管理方式,很不錯的插件哈。      

 

測試代碼下載:http://pan.baidu.com/s/1o67dAiA 密碼:l976 ,內帶有SceneManager 插件(花15大洋買的)

細雨標記: unity
 
 
作者:細雨
 
轉載請注明原文地址: http://www.cnblogs.com/zsb517/p/4113538.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM