Unity3D使用經驗總結 缺點篇


不論是從官方手冊,還是各種第三方教程,幾乎涉及到的,都是講如何使用U3D,以及U3D的優點。

雖然我是用的一個讓步語氣,但請不要否認U3D的這些優點,它們的確存在。 但對於一個引擎的特性來說,優點與缺點總是共存的。

你可以從網上了解到所有優點,但是,你很難真正體會到U3D的缺點,除非你自己被坑過。 今天,我就來細數一下U3D的缺點。 這些缺點,僅針對大中型項目。 小型項目,U3D的優點可以充分利用。

 

是不是猛的一看,全是缺點。 不要怕,想看優點的朋友,走這里  Unity3D使用經驗總結 優點篇

 

一、環境

U3D的環境可以說是非常OK的。一體式的感受,讓所有工作都無縫地進行。 真要說它有什么缺點,還很難找到。 但有幾個地方,不得不說。

1、U3D默認不支持多項目,每次打開場景,則會關掉當前場景,再打開下一個場景。 而雙擊U3D的啟動圖標,又會自動打開最近一個項目。 想要解決這個也還好辦  在快捷方式后面加上 --project即可。 加上后,每次編譯時會有一個提示,這個無關緊要。

再試試雙擊U3D的快捷方式,是不是會讓你選擇項目啦。

 

2、多個U3D版本不易共存,網上也有人提供了解決方案。但是,這始終不是太爽的一件事。

3、編輯器未和執行環境分離,若要DEBUG,必須啟動U3D編輯器。 而很多時候,對於程序員來說,是不需要的。 它們只是想改改代碼,然后編譯,執行。 或許,U3D可以通過命令行提供一個較輕量的啟動環境。

4、如果代碼中出現了死循環,那就只有強行結束U3D,然后再開。 中間如果忘了保存,那剛剛做的場景編輯工作,就洗白了。

 

二、開銷

基於Mono的運行環境,導致引擎起步價就比別人高。初始化時間過長。 這對於中高端機來說,是感覺不到的。但低端機,相比之下,就顯得尷尬了。 而這一情況,對3D的影響還好。但對於一個小型的2D游戲來說,就會被人誤認為,游戲做得不夠好。

U3D雖然提供了原生的2D支持,但是其本質僅僅是在運行期鎖定了相機,集成了BOX2D物理和2D碰撞生成器等東西。 運行時期的起步價開銷,與3D是等同的。

 

三、代碼驅動的開發模式

不管是官方示例,還是一些入門教程,都是以代碼驅動的方式來引導大家熟悉U3D。 當然,代碼驅動方式也確實很方便,同時更能章顯U3D的強大。

對於一個小項目來說,代碼驅動無疑是最便捷的操作方式。

但是,對於一個大型項目來說,代碼驅動的結果則是BUG頻繁,且很難逐一解決。 同時,對策划要求較高,策划需要知道不同對象應該掛什么樣的腳本。 而對於代碼驅動的開發方式來說,編碼的人,最好就是策划。為不同的對象,使用腳本定制特定的功能。

因此,使用U3D做大型項目的話,還是得需要退回到經典的數據驅動模式。 數據驅動模式則正好沒有代碼驅動模式面臨的問題。同時,數據驅動才能更好地做出網絡游戲。

關於這個問題,我想等有時間了,專門弄一篇文章,向大家表達一下我心中所想。

在這里,簡單地提一下腳本掛接需要注意的地方

 

U3D的組件思路是要一直沿用的,如果腳本不掛在對象上,那就失去了這個NB的特性,現在,我們要決定怎么樣掛。我的思路是,對於一個對象來說,如果是對其能力進行擴展的,那就可以將這樣的特性掛在對象身上。 反之,如果是決定游戲流程的,那這就應該是普普通通的代碼,不能掛到對象身上。

下面,舉一個簡單的例子。  玩家走到一個觸發器上,觸發器觸發,然后,玩家移到新地圖。

首先,觸發器本身是一個對象,它會檢測是否有對象進入它,如果對象 玩家,那將會被傳送。

對於一個普通的gameobject來說,是沒有檢查對象進入和觸發能力的。 那,我們可以將它的COLLIDER弄成TRIGGER。 但是,一個對象的RIGGER觸發的檢測,只能是在掛在它的對象腳本里做。

按我們上面說的原則,那當腳本里檢查觸發后,我們就不能直接操作玩家。 而是應該將這個事件拋出,由邏輯來處理。

於是,我們可以寫一個事件類,這個事件類負責管理所有事件,然后感興趣的對象,可以來對里面的事件進行接收和處理。

我們還需要一個TrigerDetector來做所有觸發器的掛接。 剩下的事情,就是真正的游戲邏輯來做了。 

 

上面是單機的情況,那網絡的情況,又怎么做呢。 這就是數據驅動的魅力了。

對於這個觸發器,我們可以掛接一個teleport的腳本,這個腳本什么功能都沒有,只有一些變量,如目標地圖ID等。另外,我們還需要將這個對象標記為SERVER對象。

然后,我們需要擴展編輯器,將場景導出。標記為SERVER對象的,則導出到SERVER使用的數據文件,沒有標記為SERVER的,則導出到客戶端的數據文件里。

然后,前后兩端進行加載和操作。至於如何導出,下面有簡單說明。

 

四、所見即所得

咦,這不明明是優點么。為毛又成缺點了。

其實,這確實是優點,而缺點其實不是因為它,而是因為U3D采用二進制存儲場景文件。那多人協作的時候,SVN沖突可是一樁接着一樁的。 

解決這個的辦法也挺簡單,我們擴展一下編輯器,將對象導出成非二進制格式不就成了么。然后再在游戲里面,重新加載。

思路是這樣,要實現這個中細節,其實也挺麻煩的。我們公司的編輯器雖然功能不多,界面不美,但是卻優雅地解決了這個問題。

這套方案也不是一兩句話能說清楚。 總之,記住,這里是個坑。

既然提到這里了,如果不說點具體解決辦法,可能有人說我是裝B了。 那我說一個能夠一定程度上解決沖突的辦法。

1、場景中所有對象,使用prefab。 不能有非prefab出現,且不能修改prefab的任何屬性

不能修改屬性的原因是為了保存的時候簡單,如果大家屬性都一樣的話,那我們只需要存它的縮放,旋轉,平移以及對應的prefab名字就可以了。 遇上需要不同屬性的東西,那新建一個PREFAB

2、擴展一個編輯器功能,將場景導出為XML或者JSON什么的文本格式

這個文本格式,保存了所有的對象信息,每個對象信息包含縮放,旋轉,平移以及對應的prefab名字。 當然,這不是死的,如果有其它需求,可自行添加。比如,對象的初始active狀態

3、新建一個真正的場景,里面只有一個GameObject對象,這個對象只掛接了一個腳本,這個腳本的初始化,就是調用游戲邏輯的初始化,這個腳本的UPDATE,就是調用邏輯的UPDATE。

這其實就是一個MAIN入口。 你的游戲邏輯應該是與具體場景無關的。 你只需要加載你先前導出的文件,然后對所有對象進行實例化即可。

 

這個是解決SVN沖突的第一步,同時也是數據驅動實現的第一步。

 

 

關於游戲的增量更新之類的坑,並不是U3D特有的,通常只有兩個解決方案,一個是數據和代碼分離,以減少更新壓力。 另一個是純腳本,實現所有功能,包括資源的加載什么的。 不管采用何種方案來應對這個問題,數據驅動是必然的。

這也是我入手U3D的原因,因為通過編輯器擴展,我找到了數據驅動的解決辦法。

 

其實,最想說的兩個問題都說了,一是數據驅動,二是SVN沖突解決。但U3D肯定不只這些坑。 但那些坑,都是很具體的,通過具體需求才能解決的。

上面講到的,是所有項目都適合的坑。希望對大家有幫助。

 

 

 


免責聲明!

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



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