原文: http://www.cnblogs.com/bambomtan/p/5116661.html
對于游戲開發(fā)而言,不同種類的游戲其架構(gòu)方式都不同,并不存在什么完美架構(gòu)模式某種類型是可以有分別的框架的,比如上帝視角ARPG,比如GAL,比如格斗,比如跑酷,比如卡牌,比如打飛機(jī)游戲。而他們使用的游戲架構(gòu)自然也是不同的。通常來說游戲項(xiàng)目最合理的方式是由一個主程根據(jù)項(xiàng)目需求制定一套新的結(jié)構(gòu)和各部分間的依賴關(guān)系,事先想好各個部分的拓展和通訊方式。有了這個過程,也就沒有硬是生搬硬套的再去套用什么模式(MVC之類). 一、一定程度上的邏輯代碼的分離,提高代碼的可維護(hù)性和 可重用性。
https://www.zhihu.com/question/23946609
我對Unity 代碼結(jié)構(gòu)組織的困惑 ,經(jīng)過各種查閱 ,發(fā)現(xiàn)其實(shí)主要是對于MonoBehaviour 上。mono必須是可是化的,要綁在GameObject上。 對于mono只做視覺上的效果,比如視覺上的特定效果(攝像機(jī)振動,飄血,特效,道具掉落,buff類),振動,變色,控制動畫,賦值點(diǎn)(控制行為參數(shù)數(shù)據(jù)),控制好它們的依賴,讓他們擁有通用性(比如道具掉落的動畫,UI動畫等),然后這些就不用再開發(fā)邏輯的時候去處理這些東西,可以丟一遍了。 而游戲的主體是一個空GameObject 上的腳本,它負(fù)責(zé)管理所有,分發(fā)事件。 其他的地方就不要出現(xiàn)MonoBehaviour了。
這樣處理的理由在于生命周期。 mono必須能看到,而邏輯往往會脫離于顯示部分,GameObject 未創(chuàng)建往往就需要有邏輯了。 也就是是說你創(chuàng)建一個人物,因該先創(chuàng)建一個MonoBehaviour類,然后在這個類的初始化代碼里創(chuàng)建一個GameObject 然后再套上各式MonoBehaviour,然后依然在這個非MonoBehaviour類處理定時邏輯和其他(定時邏輯,比如技能釋放,我釋放一個技能,由一個技能發(fā)射類管理這個技能特效的時效性)。需要時再控制下其他MonoBehaviour播放動畫、控制效果之類。 這就和其他非Unity游戲架構(gòu)沒多大區(qū)別了。
對于MonoBehaviour的邏輯分離的一個理由在于,比如現(xiàn)在對角色進(jìn)行控制,使用Character Manager、Controller (也可是說是FSM 、或者Behaviour Tree),來進(jìn)行角色狀態(tài)間的控制,將它放在角色obj上。那通常只能是人物資源的那個GameObject。那么我有個需求是換狀態(tài)的時候切換為完整的另一個資源,那么要不是Compent復(fù)制要不是創(chuàng)建子級GameObject,無論哪個都不太好吧。
或者,我想隱藏這個人物,包括里面的動畫啊和純顯示用邏輯,但是基本邏輯又想留著(否則什么時候才能恢復(fù)顯示?),本來直接將GameObject禁用就好了,現(xiàn)在這樣就不行了。或者說,它雖然有狀態(tài),但并沒有顯示,而是一個虛擬對象。但如果它不是MonoBehavior就沒有任何問題了。這就是我所說的使用MonoBehavior的隱患,其實(shí)很多人心中都默默的有這樣的感覺吧?這個隱患也是確實(shí)存在的。
當(dāng)然我也不是說MonoBehavior就完全不能用,比如受創(chuàng)變色(切換以及根據(jù)color對所有Renderer賦值以及恢復(fù)為原材質(zhì))肯定是可以的,還有什么動畫順序播放,部件綁定。但是涉及到邏輯的部分,真的建議排除掉MonoBehavior。它確實(shí)是毒瘤。 此外有些人不喜歡MonoBehavior是因?yàn)閟tart發(fā)生的不確定性,還有初始化沒有構(gòu)造函數(shù)不便。那你需要端正下思路。你看unity默認(rèn)的那些組件,你會在乎它們哪個先初始化嗎?你會在乎它有沒有構(gòu)造函數(shù)參數(shù)嗎?你不會。因?yàn)樗鼈冊O(shè)計(jì)成了你不需要考慮這些東西。所以如果你寫MonoBehavior,就應(yīng)該設(shè)法按他們的模式走,讓初始化無需顧忌順序參數(shù)直接賦值就能解決,而不是拋棄start awake自己搞個create。 而MonoBehavior的主要優(yōu)點(diǎn)就在于可以獨(dú)立使用,不依賴于環(huán)境。你建個預(yù)置拖上去設(shè)設(shè)參數(shù)就能看效果。這是它最大也是唯一的優(yōu)點(diǎn),它編碼上的不便也都是為了讓這一點(diǎn)成為可能。如果你的MonoBehavior做不到這一點(diǎn),或者你認(rèn)為不需要,那費(fèi)老大勁搞成MonoBehavior又沒用,何苦。 二 、依舊是Unity 資源組織的問題
https://www.zhihu.com/question/21070379
Unity有一些自身的約定,譬如項(xiàng)目里的Editor,Plugins等目錄作為編輯器,插件目錄等等。知名的插件會自己存放一個目錄,譬如NGUI等。 所以我們自己的代碼,一般目錄名會以下劃線開頭,譬如 “_Scripts”, “_PRefabs”等。 對于場景,文檔等目錄,用兩條下劃線,以便他們能排在最頂部。代碼用C#,別用JS。必要的話用namespace將自己的代碼括起來。我們是用namespace把自己積攢的公用庫包住。C#的注釋要認(rèn)真寫,打///就能幫你補(bǔ)全了,沒理由偷懶。每個程序文件開頭要用一段注釋寫修改Log,誰改過什么簡單留一條說明。就算用了Unity的版本管理或者Git,那些log終究會丟失,只有認(rèn)真把log寫在代碼里,才會有意識去認(rèn)真優(yōu)化它。Unity的腳本邏輯,就功能而言大體分為兩種,一種是比較獨(dú)立的,譬如爆炸之后1秒鐘消失,這種單獨(dú)寫個腳本綁定到目標(biāo)上即可。 更多的是腳本里與其它的腳本進(jìn)行交互。Unity里提供了一種萬金油的方法是SendMessage, 這種方法性能略差,如果你調(diào)用的頻率不高,隨便用也無妨。另一種方法是直接通過對象的實(shí)例去調(diào)用。我們的做法是寫幾個公用的控制器,讓它們各司其職,負(fù)責(zé)各自的事情: - 寫一個一個GlobalManager.cs來控制游戲的全局變量及全局方法。靜態(tài)類模式。譬如當(dāng)前玩到第幾大關(guān)第幾小關(guān),玩家的金幣數(shù)量等。 - 寫一個GameController.cs來控制當(dāng)前關(guān)的游戲進(jìn)程。單實(shí)例模式。游戲的主循環(huán)也是用它控制。初始化,勝利、失敗判定等等。 - 寫一個InputController.cs來控制所有的用戶輸入。單實(shí)例模式。鼠標(biāo)、鍵盤、觸摸屏,我們做游戲是保證同時支持這三種輸入的,因?yàn)榇蟛糠謺r間是在PC上測試。 關(guān)于GameController與InputController的聯(lián)系,有點(diǎn)讓人糾結(jié)。一般來講是在InputContoller里調(diào)用GameController.Instance.Foo()執(zhí)行方法。或者直接對Input寫成Listener的模式,讓GameController去監(jiān)聽。 - 其它的類似菜單控制器,聲音控制器,成就控制器,IAP虛擬道具控制器等等,也是采用類似的方法管理。 - 關(guān)于PlayerPref的操作,統(tǒng)一寫成靜態(tài)類的get/set模式,程序中哪里要用則直接讀寫。 - 如果你的項(xiàng)目里場景的數(shù)量少(<5),那么拖入場景的資源可以很隨意。如果場景數(shù)量很多(幾十個,有的解謎游戲每個關(guān)卡就是一個場景),那么拖入場景的prefab數(shù)量一定要少。 - 設(shè)計(jì)你的prefab資源里,你要想像當(dāng)其他人拿到這些資源,是否直接拖入一個空場景里就能run,頂多再簡單設(shè)置幾下。如果你設(shè)計(jì)的資源不能做到這些,那么得好好重新想想。
三、代碼原則 著作權(quán)歸作者所有。 商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 作者:feicheng wu 鏈接:https://www.zhihu.com/question/21070379/answer/24182335 來源:知乎
1.邏輯腳本基于場景劃分 2.抽離靜態(tài)配置數(shù)據(jù)、全局管理數(shù)據(jù)以及對局臨時數(shù)據(jù)的管理 3.使用單例模式創(chuàng)建不依賴于場景的游戲?qū)ο蠹捌渖系娜止芾砥?4.避免使用GameObject.Find以及SendMessage,聲明對象引用以顯示標(biāo)明腳本之間的依賴性,活用delegate解耦合 5.多用組合少用繼承(Component的架構(gòu)真的是太棒了) 6.數(shù)據(jù)行為與邏輯表現(xiàn)分離,即V與MC的分離,換句話說多寫class少寫MonoBehavior。(通常初期在快速開發(fā)原型時會把一個功能全部實(shí)現(xiàn)寫在一個繼承于MonoBehavior的腳本中,盡早進(jìn)行重構(gòu),抽離出負(fù)責(zé)數(shù)據(jù)管理與控制的類,這對于后期功能的增加與修改時很有必要的) 7.善用Coroutine(Coroutine真是太方便了) 8.盡量能夠使用自定義的配置文件輔助Prefab上腳本參數(shù)的配置。
總的來說記得知乎上看到誰說過cocos2d是程序員友好的,而Unity3D是設(shè)計(jì)師友好的,寫了這么多年Unity3D代碼我真是覺得我的思考方式越來越像策劃而不是程序員了,使用Unity3D開發(fā),寫代碼應(yīng)該只占了大概50%的工作,另外50%都在編輯器上,如果你用過相信你懂得。
著作權(quán)歸作者所有。 商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 作者:趙忠健 鏈接:https://www.zhihu.com/question/21070379/answer/65360313 來源:知乎
unity是基于組件開發(fā) 一上來確實(shí)不太適應(yīng),也跟同事討論了好久,至今沒什么太好的結(jié)論。說下我們的方案, 一.啟動場景一個 object上掛腳本主入口,他負(fù)責(zé)驅(qū)動游戲內(nèi)所有manager的創(chuàng)建,更新及銷毀。 二.人物,AI等需要繼承的通過持有g(shù)ameObject來是實(shí)現(xiàn)。而不是掛載到gameObject上。 三.基礎(chǔ)功能通過組件實(shí)現(xiàn)。掛載到gameObject上。(邏輯表現(xiàn)分離) 總體上就是最基礎(chǔ)層面 負(fù)責(zé)具體功能的用組件來降低耦合度,這樣也清晰。而一些需要始終存在的或者需要繼承則通過原來的方式,創(chuàng)建腳本對象,然后持有Object,這是這個object不在負(fù)責(zé)具體邏輯,只是各個基礎(chǔ)功能的總和。
著作權(quán)歸作者所有。 商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 作者:歐宇龍 鏈接:https://www.zhihu.com/question/21070379/answer/76962412 來源:知乎
有句話,我總會仔細(xì)的跟很多朋友講到 做游戲,牛逼的不是實(shí)現(xiàn)某一個功能,而是把成百上千的功能放到一起,卻不亂。
而我認(rèn)為,這條路,必須自己不斷總結(jié)反思。別人給的經(jīng)驗(yàn),往往并不一定合適具體的項(xiàng)目。 不管別的,有幾個標(biāo)準(zhǔn)可以檢驗(yàn)?zāi)愕拇a是否合理
1:美術(shù)資源 提交后,策劃配表提交后,不需要程序變換,即可立馬看到結(jié)果。 比如,一個圖標(biāo)變了,美術(shù)可以打包圖集,提交。 策劃變了一個配表,他可以直接提交配表。 一個新的怪物出現(xiàn)了,讓美術(shù)自己提交怪物資源….. 最后他們自己跑游戲里一看,發(fā)現(xiàn)東西是OK 的。 不管你程序如何設(shè)計(jì),這事是最重要的一條。 簡單來說就是 讓美術(shù)和策劃能夠提交后直接看到結(jié)果。
2:游戲暫停時,能否直接通過 視圖窗口,看到盡量多的游戲當(dāng)前狀態(tài)。 以我做的ARPG為例, 再某一下,我一刀揮出去,打到一個怪物了。 再怪物受擊的那一瞬間,我點(diǎn)擊暫停。 這個時候我點(diǎn)擊怪物這個GameObject,可以看到怪物當(dāng)前正在播放那個動畫,重力是多少,重力加速度是多少,受擊的效果有哪幾個,數(shù)值分別是多少… 可以通過視圖窗口看到當(dāng)前怪物移動組件是否使用中,AI 組件是不是被停滯掉了 ……… 這個點(diǎn)是存在爭議的,諸多從C++過來的朋友,cocos寫得多的朋友。并不習(xí)慣組件化這樣的東西
3:是否一個類只干一件事 這個同樣很重要 甚至可以說是需要被確保的。組件化或許這點(diǎn)有些爽。就是基本確保了你寫的某個組件只干一件事。
| 
 
 | 
新聞熱點(diǎn)
疑難解答