天天看點

Unity3d之無縫地形場景切換–解決方法和代碼

當我們開發一個大型項目的時候-會遇到這樣的問題(地形場景的切換)這個隻是字面意思-并不是重場景1的100 100 100坐标一下切換到場景2的100 100 100坐标這樣的方法--(如果您以為是這樣的技術和代碼)那就不用看了。這個技術的實質意義是為了解決--多地形場景帶來的大量記憶體占用問題-舉個我的例子-我的測試項目是1013張繪制地形--在不用上面的技術情況下-占用了我4.2g的記憶體。想想下-如果一個大型的遊戲直接這麼運作的話)一下就會帶來5-8g的記憶體占用--這個遊戲還能玩嗎?

下面讓我們來研究實作的方法和代碼

涉及到幾個u3d函數:(引用高人的文檔介紹)

application.loadlevel(lv) 場景讀取(記着用多場景前要現在file-build setting裡登記下場景,才能在腳本裡讀取到) dontdestroyonload(object) 保持物體在場景切換的時候不被解除安裝(能保持他的所有屬性哦)

*assetbundle 類 預讀資源(主要用于web3d,運作時實時從伺服器下載下傳需要的場景資源)

涉及到幾個基礎知識:

static 靜态類、靜态變量:在整個遊戲中都不會被重新加載,是以可以當全局全場景變量使用,主要用于記錄場景數組。

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

2.制作場景邊界

使用cube + istrigger=true屬性是最好的辦法。

1)如果是雙場景切換,注意兩個場景邊界坐标别重在一起,不然你走到邊界會發現兩個邊界不停的切換=.=,要讓2個場景邊界互相交錯一起(做的時候你自然會明白)。有必要的話,邊界可以往裡面縮一點(甚至可以吧場景重疊1/3,但這樣兩個場景你要做很多重複的東西),避免使用者看到邊界。然後建議是把cube

3.編寫腳本

好了,現在可以開始寫腳本了,我一如既往的很懶,是以不會吧全部代碼粘帖出來 。(我會别看到這裡不看了,這是以前高人寫的)

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

1.是主錄影機走到邊界才會做場景加載或解除安裝動作。是以代碼是放在主錄影機上或者主角上。

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

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

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

function ontriggerenter(other:collider){

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

}

上面的介紹是大概的描述-具體實作方法如下

我們在使用這個技術之前要将你的地形--在u3d裡的file-build setting裡登記下場景,才能在腳本裡讀取到-add current(這個是登記地形)

之後我們來制作一個簡單的-2個地形的切換方法

這個圖是做好了的2張地形--中間的cube是用來接受角色的碰撞的--這樣我們就知道在何時去載入我們的下張地形場景了(不包括其他-資料。。列入--坐騎這類的-這個需要另一段代碼單獨給坐騎-馬或者車子這類的--還有很多)

cube---把inspector--is trigger--劃勾--(這個作用是接受碰撞但不産生能量傳遞-也就是說他接受碰撞,但可以讓同樣具有 is trigger-劃勾的屬性物體通過--列入-我們的角色或坐騎)(補充--我們的角色也需要去勾選-is trigger-這些才可以通過,但官方自帶的fps--沒有is trigger-這個勾選像-可以用如下方法解決-建立一個新的cube為他重新命名-把他作為fps-父物體--然後勾選-cube的 is trigger-子物體就會有這項屬性了)

這些工作建立好了以後-開始我們的腳本工作。

腳本如下:

function ontriggerenter(other:collider)

{

if (other.gameobject.name=="cube1")

application.loadlevel("terrain 1");

};

複制代碼

為了友善大家了解--我沒有重新命名--cube1--就是我們接受碰撞體,terrain 1是我們的要載入的下張地形。(大家可以用很多方法去優化他--有優化的方法請發在這個文章内-友善大家檢視-非常感謝)

這段代碼要放在角色上或角色錄影機上或fps的父物體cube上。

以上的操作就完成了-一個重地形0到地形1的切換--(可以解決100m或跟高的記憶體占用問題-這個要看你的地形場景而定了)

但這并不完整--我們也可能要重地形1回到地形0---這個要你們自己解決了-以上的内容已經把這個解決的方法說出來了--大家自己學習發揮下--這樣才有進步。

下面我們來說明4張地形場景的載入--邏輯(這裡隻說明邏輯,具體代碼和上方一樣,需要大家自己發揮下)

這個圖中可以看到4張地形場景--我重點講解--中間的2個大的cube邏輯--那4個長方形的大家應該都清楚了。除非你沒認真看。

中間最大的cube是來判斷--角色走的這個範圍内的時候他要去載入那張地形場景-如果在這個大的cube的範圍内折載入其他的2張地形場景。(這個大的cube可以根據自己的地形規格-做出調整這裡給出的并不準确)

中間最小的cube是來判斷--角色走的這個範圍内的時候他要去載入那張地形場景-如果角色走入小的cube中後-載入其他3地形。

原文連結:http://keigoliye.blog.163.com/blog/static/146213359201081923658957/

簡介:09年入行,喜歡遊戲和程式設計,對3d遊戲和引擎尤其感興趣。 

版權聲明:本文版權歸作者和部落格園共有,歡迎轉載。轉載必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

繼續閱讀