寫(xiě)在開(kāi)頭牺弄,對(duì)于任何非尖端型研發(fā)項(xiàng)目的技術(shù)選型,我的忠告:
不要造次
江湖X技術(shù)選型
客戶(hù)端: Unity(C#+lua)
服務(wù)器: SCut(C#)
數(shù)據(jù)庫(kù): redis宜狐、mysql
關(guān)于客戶(hù)端游戲引擎
Unity目前是势告,未來(lái)幾年內(nèi)也將會(huì)是中小型游戲工作室的最佳游戲引擎選擇蛇捌。
從開(kāi)始使用unity前,我對(duì)上面這句話咱台,深信不疑络拌。
到我們使用unity后,我對(duì)上面這句話回溺,更加深信不疑春贸。
技術(shù)選型的過(guò)程
使用unity其實(shí)我們沒(méi)有太多的疑問(wèn)。
Unity的強(qiáng)大之處遗遵,我就不贅述了萍恕,有興趣的同學(xué)自行翻閱官方資料和業(yè)界評(píng)價(jià)。此處只說(shuō)一下我當(dāng)時(shí)的思路歷程
在開(kāi)始做《金庸群俠傳X》以前车要,我就開(kāi)始關(guān)注了一系列當(dāng)時(shí)的游戲引擎或圖形開(kāi)發(fā)庫(kù)(可以見(jiàn)我更早期的博客)允粤,包括SDL、HGE屯蹦、FLASH等等维哈。
后來(lái)嘗試過(guò)使用silverlight/WPF框架(金X在0.6之前的版本,就都是使用silverlight開(kāi)發(fā)的)
決定使用unity是當(dāng)時(shí)需要將《金X》移植到手機(jī)平臺(tái)登澜,考慮到代碼的通用性阔挠,我們便采用了同樣使用C#編程語(yǔ)言開(kāi)發(fā)的Unity。移植比較順利脑蠕,當(dāng)時(shí)大概只花了2天左右的時(shí)間购撼,就初步完成了。
我當(dāng)時(shí)同樣嘗試了FLASH的方案 AIR/Starling框架谴仙,我花了大概4天時(shí)間將游戲初步移植迂求,但發(fā)現(xiàn)其整體開(kāi)發(fā)效率、直觀性等一系列均落后與unity晃跺,考慮更多的是揩局,unity社區(qū)非常繁榮,而flash正日薄西山掀虎,所以我放棄了FLASH體系凌盯。
眾所周知,近幾年主流的跨平臺(tái)手機(jī)游戲引擎是cocos2d和Unity烹玉,cocos2d主要使用C++開(kāi)發(fā)(最近貌似在大規(guī)模推cocos2d-js以及配套的大量集成開(kāi)發(fā)環(huán)境)驰怎,而Unity使用C#——在開(kāi)發(fā)效率上,我認(rèn)為unity幾乎完勝二打。
而我認(rèn)為县忌,在小型獨(dú)立游戲工作室,開(kāi)發(fā)效率大于一切。
關(guān)于編程語(yǔ)言
我個(gè)人非常喜歡 C#語(yǔ)言症杏,我曾經(jīng)使用過(guò)非常多的編程語(yǔ)言(如C装获、C++、PASCAL鸳慈、python饱溢、perl喧伞、C#走芋、java、javascript潘鲫、php翁逞、AS、ruby溉仑、lua挖函、LOGO……),C#和python毫無(wú)疑問(wèn)是我用的最爽的編程語(yǔ)言浊竟。
寫(xiě)在前面怨喘,當(dāng)然C#毋庸置疑寫(xiě)代碼的時(shí)候很爽,但實(shí)際跑在生產(chǎn)環(huán)境中的時(shí)候振定,坑還是不少必怜。特別是很多寫(xiě)法在不知道實(shí)現(xiàn)原理的情況下,沒(méi)有經(jīng)驗(yàn)的程序員很容易寫(xiě)出性能非常低下或者開(kāi)銷(xiāo)非常大的代碼后频、或者是Unity的.NET subset不支持梳庆、抑或是iOS的一些特性導(dǎo)致不支持的代碼,這里我會(huì)在后續(xù)的博客中總結(jié)說(shuō)明卑惜。
這種隱性約束的坑膏执,不趟一遍永遠(yuǎn)是不會(huì)注意的。
另外露久,使用lua語(yǔ)言進(jìn)行熱更新已經(jīng)幾乎是行業(yè)標(biāo)配:lua是非常非常適合游戲開(kāi)發(fā)的腳本語(yǔ)言更米。
關(guān)于熱更新這里簡(jiǎn)要說(shuō)明一下:
熱更新:在游戲中不升級(jí)客戶(hù)端安裝程序的情況下,對(duì)游戲進(jìn)行更新毫痕。也稱(chēng)游戲內(nèi)更新征峦。
ulua提供了高性能的靜態(tài)/動(dòng)態(tài)綁定,來(lái)實(shí)現(xiàn)和C#的交互镇草。(雖然也有很多坑?籼怠)
我們將在后面單獨(dú)一節(jié),講解熱更新機(jī)制的設(shè)計(jì)及實(shí)現(xiàn)梯啤。
關(guān)于UI系統(tǒng)
在Unity下竖伯,UI系統(tǒng)有若干解決方案。目前主流使用的是NGUI,大量基于unity的商業(yè)游戲也證明了NGUI的可用性七婴。
我自己當(dāng)時(shí)通過(guò)反復(fù)對(duì)比祟偷,認(rèn)為UGUI一定是未來(lái)的發(fā)展趨勢(shì)(畢竟官方支持),所以即使有非常多的坑打厘,我也愿意和unity的成長(zhǎng)一起來(lái)趟修肠。
主要是我認(rèn)為NGUI的很多實(shí)現(xiàn)方式感覺(jué)像在一個(gè)3D引擎上打補(bǔ)丁,而非優(yōu)雅的解決方案户盯。讓我用起來(lái)非常別扭嵌施,而UGUI更加強(qiáng)大的所見(jiàn)即所得的編輯模式吸引了我。
在此插句話莽鸭,我還是非常中肯的認(rèn)為吗伤,微軟的Expression Blend是我曾經(jīng)用過(guò)的最好的UI builder工具!
所以我們第一時(shí)間入了當(dāng)時(shí)并不成熟的UGUI的坑(Unity4.6)硫眨,并且為之付出了非常沉重的代價(jià)(如中間很長(zhǎng)一段時(shí)間的UI bug導(dǎo)致閃退)
目前來(lái)看足淆,我還是認(rèn)為值得。并且為堅(jiān)持當(dāng)時(shí)自己的選擇感到欣慰礁阁。
Unity團(tuán)隊(duì)一直在很努力的改進(jìn)UGUI巧号,其以肉眼可見(jiàn)速度在完善。綜合我們的開(kāi)發(fā)效率來(lái)看姥闭,其易用性丹鸿、性能均可,穩(wěn)定性還有可提升空間泣栈,但目前及時(shí)開(kāi)發(fā)商業(yè)級(jí)游戲卜高,也屬于完全可用狀態(tài)。
關(guān)于服務(wù)器游戲引擎
不同于大部分游戲開(kāi)發(fā)團(tuán)隊(duì)南片,我希望服務(wù)器和客戶(hù)端使用完全一樣的開(kāi)發(fā)語(yǔ)言掺涛。
好處:
- 程序員只需要學(xué)習(xí)/精通一門(mén)語(yǔ)言,利于后期擴(kuò)展團(tuán)隊(duì)
- 我并不希望嚴(yán)格的區(qū)分客戶(hù)端和服務(wù)器程序疼进,因?yàn)槲艺J(rèn)為兩者本身就是一體的薪缆。一個(gè)合格的程序員應(yīng)該從前端到后端可以獨(dú)立完成一個(gè)模塊。
- 客戶(hù)端和服務(wù)器可以共享同樣的數(shù)據(jù)結(jié)構(gòu)伞广,并且是一份代碼(甚至一個(gè)dll)
- 可以隨時(shí)將代碼從客戶(hù)端挪到服務(wù)器拣帽、或者從服務(wù)器挪到客戶(hù)端,進(jìn)行非常靈活的計(jì)算部署或數(shù)據(jù)驗(yàn)證(甚至可以像開(kāi)發(fā)單機(jī)一樣來(lái)開(kāi)發(fā)網(wǎng)游)
通過(guò)調(diào)研后嚼锄,我們挑選了國(guó)人寫(xiě)的游戲服務(wù)器引擎Scut作為開(kāi)發(fā)框架减拭。
當(dāng)然,從一開(kāi)始区丑,我們就規(guī)劃了服務(wù)器群組的概念拧粪,這個(gè)我會(huì)在后續(xù)的文章中講解修陡。
服務(wù)器結(jié)構(gòu),我們也劃分了諸如賬號(hào)服務(wù)器可霎、游戲服務(wù)器魄鸦、計(jì)算節(jié)點(diǎn)服務(wù)器等⊙⒗剩基于更長(zhǎng)遠(yuǎn)的業(yè)務(wù)邏輯規(guī)劃拾因,賬號(hào)服務(wù)器我們目前使用J2EE的框架開(kāi)發(fā)的,提供RESTful接口給游戲服務(wù)器調(diào)用旷余,此處不贅述绢记。
關(guān)于數(shù)據(jù)庫(kù)
KV型數(shù)據(jù)庫(kù)和關(guān)系型數(shù)據(jù)庫(kù)各有合適的應(yīng)用場(chǎng)景,所以我們兩者同時(shí)使用荣暮。
Redis
一些高頻訪問(wèn)庭惜、游戲業(yè)務(wù)邏輯嚴(yán)密相關(guān)的數(shù)據(jù)罩驻,我們均放在redis里穗酥。并且我們?cè)O(shè)計(jì)了一套原創(chuàng)的ORM框架,來(lái)實(shí)現(xiàn)C#的POJO到KV型DB的映射惠遏。
此框架極大的利于我們提升開(kāi)發(fā)效率砾跃,我們永遠(yuǎn)只需要關(guān)注邏輯實(shí)現(xiàn),而不用關(guān)心底層存儲(chǔ)节吮。為了節(jié)省傳輸帶寬和計(jì)算資源抽高,我們實(shí)現(xiàn)的ORM框架保證了所有的數(shù)據(jù)增量同步。
有時(shí)間的話透绩,我將會(huì)在后續(xù)的文章中詳細(xì)的介紹本框架翘骂。或者有必要的話帚豪,我們會(huì)考慮開(kāi)源碳竟。
同時(shí),我們還在依托于redis的查詢(xún)性能做了大量活躍數(shù)據(jù)的存儲(chǔ)(相當(dāng)于充當(dāng)了memcache的角色)狸臣,這樣比自己開(kāi)發(fā)代碼級(jí)緩存或在mysql里緩存性能要高許多莹桅。
MySQL
沒(méi)有太多好說(shuō)的,一些賬號(hào)關(guān)鍵數(shù)據(jù)烛亦,我們使用mysql記錄诈泼。
后續(xù)優(yōu)化方案
為了提高服務(wù)器性能及單位硬件內(nèi)支撐人數(shù),合理的處理并發(fā)擁塞煤禽,我們后續(xù)會(huì)引入MQ(消息隊(duì)列)铐达、基于對(duì)象數(shù)據(jù)庫(kù)或OSS的多級(jí)緩存機(jī)制,我會(huì)在后續(xù)的文章中詳細(xì)說(shuō)明檬果。