1. 程式人生 > >Unity3D無縫場景切換解決方案 - 簡單場景切換

Unity3D無縫場景切換解決方案 - 簡單場景切換

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

所謂無縫場景切換,無非是涉及到場景或物體的預讀,複雜點涉及下場景解除安裝,在複雜點涉及到場景二維陣列,再在複雜點涉及資料結構用二叉樹實現場景資源有序的讀取與解除安裝。當然,複雜的我以後慢慢再說,比較懶,先寫最簡單的,如果能起到拋磚引玉作用,那這篇文章也算是物有所值了。


  無縫場景切換的優缺點:


  優點:


  1.場景(遊戲)連貫性。


  2.相對於多場景遊戲,不需要等待場景更換(在進入場景後已經在實時載入下一個場景了)


  3.相對於單個大場景,這種方式能避免所有的場景資料被裝入記憶體(儘管U3D優化很好並不會被渲染出來),很大的資料在記憶體裡影響你遊戲的效能(特別是在iphone這種小記憶體環境)。


  缺點:


  1.操作繁瑣(本文介紹比較基礎簡單的方式)


  2.開發者要求較高(注意保持邏輯清晰,不然後期你會全亂掉的)


  涉及到幾個U3D函式:


  Application.LoadLevel(lv)     場景讀取(記著用多場景前要現在File-Build Setting裡登記下場景,才能在腳本里讀取到) DontDestroyOnLoad(object)  保持物體在場景切換的時候不被解除安裝(能保持他的所有屬性哦)


  *AssetBundle 類       預讀資源(主要用於web3d,執行時實時從伺服器下載需要的場景資源)


  涉及到幾個基礎知識:


  static 靜態類、靜態變數:在整個遊戲中都不會被重新載入,所以可以當全域性全場景變數使用,主要用於記錄場景陣列。


  Collider的Is Trigger屬性:設定成True,他是可以穿越不會產生能量傳遞的,但是,他是可以接受碰撞偵測的。配合主角的OnTriggerEnter事件,就可以知道你是否正在穿越一個Trigger了。在這裡,我們用在判斷何時載入新場景上。


  簡單的無縫場景切換方案:


  1.建立場景(已經做好很大場景的就準備做切割吧)


  場景儘量小,如果是web3d,那需要更小,已保證場景在網路上傳輸時間不至於太長,在漫遊中再實時讀取其他場景資料。一般來說,場景大小考慮因素有兩種:如果是web3d模式,考慮網路傳輸速度;如果是pc,mac,wii,iphone,那就得考慮記憶體或視訊記憶體能吃你多少場景資料並且處理起來不費力。


  按照你所需要建立的無縫場景切換方式,你可以按場景的座標建立以下幾種方式:


  1 ) 雙場景切換(本文重點)                2)九宮格場景切換


  1)雙場景切換:用於單個場景較大的情況。同一時間只加載1個到2個場景(預讀周圍4個場景),場景間需要交錯,避免讓使用者看到場景的邊界深淵=.=.當用戶走到邊界,就載入下一個場景,如果走到4個頂點,載入下兩個場景(如果場景龐大應儘量用障礙物避免使用者走到頂點,因為走到頂點要載入的資料是走到邊界載入的2倍-,-)


  2)九宮格場景切換:用於單個場景較小的情況。因為同一時間需要在記憶體中載入以使用者為中心的周圍(包括本地)9個場景資源,不同於雙場景切換的是,場景間不需要交錯,因為使用者視野永遠不會看到當前場景界限。用9宮格方式需要將場景預先存入靜態的二維陣列,以便讀取使用。


  2.製作場景邊界


  使用Cube + IsTrigger=True屬性是最好的辦法。


  1)如果是雙場景切換,注意兩個場景邊界座標別重在一起,不然你走到邊界會發現兩個邊界不停的切換=.=,要讓2個場景邊界互相交錯一起(做的時候你自然會明白)。有必要的話,邊界可以往裡面縮一點(甚至可以吧場景重疊1/3,但這樣兩個場景你要做很多重複的東西),避免使用者看到邊界。然後建議是把Cube的名字設定成鄰接場景名稱,因為待會兒寫指令碼時候方便。


  2)如果是九宮格場景,那就不需要重在一起了,邊界Cube名字建議使用本場景的名字,因為這樣你一走到下一個場景,就可以知道你在的場景位置而讀取周圍新場景了。


  3.編寫指令碼


  好了,現在可以開始寫指令碼了,我一如既往的很懶,所以不會吧全部程式碼粘帖出來[unity3D]無縫場景切換解決方案(1) - 簡單場景切換 - kingmax_res - kingmax_res的部落格。


  先理清楚邏輯關係以及一些常識:


  1.是主攝像機走到邊界才會做場景載入或解除安裝動作。所以程式碼是放在主攝像機上或者主角上。


  2.場景可以載入,但是沒有解除安裝場景這個東西(也沒必要解除安裝,因為同一時間只會有一個場景為當前場景),所以如果你用九宮格方式做無縫連線,你需要把場景讀取,然後讓場景裡所有物體DontDestroyOnLoad(當然包括主角,也就是this),然後其他場景也這麼操作,當需要解除安裝場景時,只要把所有那個場景Object給Destroy掉就可以了。而做雙場景連線則不需要這樣,也簡單的多。


  3.如果是九宮格,你需要一個靜態二維陣列去記錄每個位置場景的名字。這裡也可以不需要這麼做,有個技巧,你可以格式化場景名字規則來推算下一個需要載入的場景名字,比如M1N1表示(1,1)場景,那你就可以用字串拆分的方法知道需要讀取M0N0,M1N0,M2N0等等的場景。


  4.接下來就是處理碰撞,獲取下一個場景(雙場景方式)或者當前場景(九宮格方式)的名字,這裡你就可以看到一個被格式化過的場景名有多麼重要。


  function OnTriggerEnter(other:Collider){


  Application.LoadLevel(other.name);  //這是雙場景方式直接把邊界Cube名字設為了下一個場景名


  }


  更加複雜化的無縫切換方案思路:


  1.使用角色與邊界距離動態判斷,以確定載入時機以及載入哪個方位的場景。


  2.加入判斷角色為中心的圓內的物體載入(操作起來有點複雜,除非你整個場景是數字化的,或者乾脆是動態生成的),這需要一個加權的二叉搜尋樹將大地圖所有的物體放進去,在滿足條件時候去載入最近的。


  (僅提供思路,可能有更好的資料結構去優化他)

轉自:http://www.unitymanual.com/thread-5573-1-1.html



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述