Unity3D 之腳本架構,優雅地管理你的代碼


本文參考雨松MOMO大神的帖子:

圖片全部來自他的帖子(請允許我偷懶下)

------------------------------------------------------------------------

寫代碼,我相信大家都會,但我看過不少網上的源代碼,發現很多人代碼寫得很隨意,

想到什么寫什么,沒有個固定的框架,代碼亂,高耦合,不僅看起來不舒服,以后要維護也非常困難,

而且還容易出現一直莫名其妙的BUG。

吶,本人有點小潔癖,有點強迫症,雖然我還只是個菜鳥,但我卻非常在意代碼的寫法,非常講究

結構,今天我就把我的心得以及雨松MOMO的帖子講講要怎么寫:

如下圖所示,任何平台下的任何游戲核心都是由:數據、邏輯、渲染三大部分組成。

game_all

如下圖所示,Unity3D這套游戲引擎在游戲開發中的權重如圖中所示。其中包含100%的渲染部分 +50%左右的邏輯部分。(因為Unity3D封裝了很多與邏輯相關的API供開發者使用)

game_in_unity

下面我們回到Unity3D腳本架構的編寫上,我們知道Unity3D在是可以創建游戲場景的,在每個游戲場景中又可以創建游戲對象,把每個場景的游戲對象融合在一起就是一款3D游戲。游戲場景之間屬於同等級的關系,為了讓游戲場景之前交互我們需要有一個凌駕所有場景之上的腳本,我稱之為“全局腳本”。如下圖所示,所有場景都能與這個唯一的全局腳本進行交互。當場景切換時可將臨時邏輯數據寫入全局腳本中,切換完畢后再去全局腳本中取之前保存的數據,從而實現交互。(當然還有別的辦法也能實現這個效果,但是我覺得這樣做會更好一些,數據會更安全一些)

例如:游戲戰斗時你獲得一定數量的金幣,當你返回菜單界面時,你仍然能看見UI界面顯示你的金幣數量,這就是全局交互。

又或者,大部分游戲Loding時都只有一個Loading場景,A場景轉到B時調用這個場景,B轉到C也是調用這個Loading場景,

那么Loading場景要怎么知道接下來讀取哪個場景?當然是通過你將全部場景的名字存到全局變量,然后讀取的時候指定了。

unity_scene_data

接着我們就進入場景中,游戲場景是由若干游戲對象組成,下面我好好說一說游戲對象。游戲對象是需要綁定游戲腳本才能完成它的生命周期。那么腳本的使命就會尤其的重要。因為游戲對象比較多那么腳本必然會出現交互的情況,如下圖所示,很多初期Unity3D的項目中的腳本會編寫成這個樣子。錯綜復雜相互交互,這樣編寫的腳本有可能你的游戲能做出來,可是你在維護的時候團隊開發的時候你會發現你的腳本非常的混亂,別的同事想改都不知道怎么改。(顯然這樣的作法時完全錯誤的)

wrong_struct

 

游戲中盡量避免這種高耦合的方法,比如由於某些變動,上面圖片的腳本4需要修改或者刪除,那么也必須更改腳本1,2,3,5與其的交互,不然會出錯。

這種高耦合的方法顯然非常累,而且還容易出錯,比如你忘了更改腳本3與腳本4的交互,那么就出錯。

 

我們想想為什么腳本之間要交互,原因很簡單。是因為腳本中需要使用/調用另一條腳本或者另一條腳本對應的游戲對象某一項數據/方法,為了解決這個問題而導致最終的腳本非常混亂。為了避免這個問題,我在開發中會這么做,如下圖所示,腳本之間切記不要做直接的相互交互,腳本之間只做間接的交互。每一個游戲場景都有一個凌駕所有游戲對象之上的單例腳本,在這條腳本中保存場景中所有腳本的公共數據。包括該場景的整體邏輯更新都是在這條單例腳本中完成。每條腳本都只與這個單例腳本做交互,和別的腳本一概不交互。(間接交互)

right_struct

 

或者使用消息通知中心來實現解耦也可以:

(需要注意的是,Unity自帶的消息中心很爛,效率不高,也沒有訂閱功能,需要自己擴展)

 

編寫腳本時請注意,腳本只干屬於自己最重要的事情,就跟代碼中的函數一樣,只干最重要的事情。切記和該條腳本無關的事情不要去管,不要在腳本中做過多的相互連帶工作,讓所有連帶工作的話都放在全局單例腳本中來做。

 


免責聲明!

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



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