Unity老司機:我們是如何做引擎優化的

轉載自:http://z.youxiputao.com/articles/8313


在4月12日的Unite 2016大會上,暴風魔鏡高級產品經理吳濤分享他用Unity3D開發VR遊戲的經驗,以下爲分享實錄:

我自己是從2010年開始使用U3D開發,之前是做大型端遊,也用過虛幻引擎。2010-2011年,中國移動遊戲開始爆發,就轉到U3D做一些U3D手遊開發,去年加入暴風魔鏡從事應用開發。

首先給大家分享一下我做Unity開發的積累的經驗吧,最早在去年的時候呢,我從手遊的開發轉到了VR開發。當時,我們的產品迭代週期是比較快的,而且還在使用Unity4.X某個版本,剛剛接手VR開發的時候很多問題開始暴露,比如我們的資源製作成本增加,資源量增多,性能指標提高很多,網絡環境要求更加苛刻,基於這些東西,我們也做了一些基於U3D自己的優化。



基本上大家從事VR開發的時候,還是需要一些基礎團隊的,建議大家都有工程師。大規模的話,還需要一些U3D工程師。目前我們團隊有4個安卓,還有6個U3D工程師。安卓做接口界面,還有C++開發。

首先,第一要介紹一下我們的版本管理。我們當時最早我在做這一塊的時候,當時還是用了三點幾的版本,我們服務器要進行OTA更新,當時設計了一個版本管理的配置文件,大家可以看到基本上我們的製作方式是在右面,有每個資源的命名,還有一些標誌是否被壓縮,比如說最後具體的路徑。



我們當時發現加載有點緩慢,所以之後把加到了VersionList上面,然後就進行二次拼接,這樣保證本地版本和服務器版本的一致性。

爲了去做剛纔的版本管理的表,我將我所有的資源進行了一個大概的分類,對每一個分類都增加另外一套配置,可以看到那面,包括我們自己自定義的所有文件的合成,同樣會帶來一些路徑,帶來一些資源的ID,帶來一些平臺,當然也有類型壓縮很多種方式,是否跟焦點綁定。



資源大概生成的過程的話基本上就是這樣子,我們會自己寫一個類似於生成的工具,然後我們資源製作完之後會放到自己的資源夾子,是跟美術資源分離,但會存在一個預製體和資源捆綁關係,將預製體進行build生成Assetbundle,我將原有的進行更新,再重新寫我的VersionList,保證自己的新生資源和老資源是一致的。


大家都知道一般現在老的Unity版本經常資源會有一些泄露,比如說我們的美術資源經常被別人反編輯出來拿到圖片拿到模型,所以說當我生成這個之後,在那裏做一次資源的加密,當時製作是比較簡單,現在會加更復雜的算法,比如一些越界對稱非對稱之類的,加這個之後呢我們遇到另外一個問題就是,因爲VR,很多模型不像之前做手遊可以刪除一些,貼圖可以小一些,他很大,這裏的話資源加密之後又做了自定義壓縮,當時我們找了很多相關的庫,最後是通過我自己的源碼,自己重新改過了一個自定義壓縮庫,他基本上我們在做完這步之後比以前的降了30%左右。

最後是資源管理和內存管理,我當時做的時候也是有一點困難,但是我當時就很慶幸的時候認識一個U3D工程師,首先是如果有相關連的時候會有三個遊戲對象,當我釋放一個的時候只將其中一個對象把他Release掉,另外兩個不會,同樣第二個釋放掉也會把第二個Release掉,第三個全部Release掉的時候我彩繪全部UnLoad,有效降低內存使用,不會產生任何內存泄露。


同樣基於剛纔的算法,增加一個索引表,增加一個索引計數,做一些++和--的操作,直到Index爲零的時候才釋放Bundle。


另外這是網絡更新,大家做網絡更新很多人還用U3D提供的3W接口下載,很早的時候一直採用那個接口,大概4年前到5年前做過一款3D的ARPU,當時我要滿足我的腳本跨平臺,要保證足夠的效率,解決一些崩潰性的問題,那個時候自己基於HTV接口實現3G緩衝下載,下載中會在內存中存放小的斷點內存數據,之間的去寫數據,然後當這個小的斷點數據拿到內存值寫到硬盤,之後下載到本地,下載完成跟本地文件進行拼接,在中間的小內存處理過程中會定期的去清理我的緩存,我知道大家有很多其他的接口可以完成緩存,但內存開銷比較大。



我會開一個多線程去下載,這個下載效率我經過以前在CDA測試,可能不是太權威的測試,性能可以提升大概30%到50%,另外就是Json數據優化,那時候網絡很差,都是3G和2G,那時候屬於短連接的狀態,發現最大的問題就是數據量很大,每次大家要等很久的時候,後面我做序列化壓縮,壓縮算法很簡單,我每一次遇到List相關的我只保留第一個值,多餘的相同的全部隱藏,這樣當數據量比較大的時候,我們平均大概能優化70%的量。

另外就是一些渲染性能,我們如果大家最近在用U3D5.4Beta版本可以發現裏面增加很多接口,比如說GPU,當時在我們使用的版本中是沒有的,當時遇到了很多渲染性能的問題,因爲當時的項目要求就是效果要好,畫面要極致,但要流暢,所以當時做了很多擴展。



有過開發經驗的人比較清楚我們的做法,基本上是進他們進行各種類型的合併。包括UV包括Texture。因爲當時合併貼圖性能非常差,我們當時是在網格合併索引合併頂點顏色的操作都是很快速完成,但貼圖的合併當時是非常非常的延遲,那個時候我沒有辦法,就開始做一些C++擴展,在這裏我們建了一個共享線程,用GPU實現貼圖拼接,然後他是一個異步進行的,渲染過程中可能會有很多模型,但是可能在一開始進行的時候會有點慢,但你加載過程之後可能大概幾秒之後會把他合成一個周扣,就瞬間性能提升下來,如果5.4大家可以去看U3D的接口,應該跟這個類似的算法。


有針對性的去使用着色器,在去年和前年的時候我在北京很多遊戲公司的工程師還有老闆去找過我,就說我們的遊戲就性能很差,就是很多的機器跑不起來,或者很多的跑的不流暢,突然到某個角落的時候就開始卡了一下,我一般去到他們公司第一件事情看他們的文件夾,就說你的着色器到底有多少,美術使用多少,因爲在中國來說很多美術的經驗比較少的,可能對技術對渲染瞭解並不是太多,比如像一些可以用多少網格,多少三角形,有多少頂點,多少張貼圖,場景可以做多大,我要佔多少內存,其實這種有數據指標的東西比較好掌握合理解,但是涉及渲染的時候,他們用起來開始產生困惑,比如經常看到一些公司裏面的一些遊戲,他很簡單的一個遊戲的模型,他要表達一個效果,然後他可能會使用很多的寄存器和很多的貼圖,但美術在使用着色器上只會用幾個參數和幾張貼圖,那個時候當時也分析了他們的一些訴求,所以基於他們的渲染需求,我自己寫了很多的着色器方便他們做各種各樣效果,當他們效果匹配的時候,基本上讓他們的着色器達到最優化,分析ALU,讓他每次的每個使用是最優化的,不會有多餘浪費和冗餘。


我也是參考了一些插件中,一大部分是我自己寫的,另外就是地形系統,最早我們就發現網格數比較大,比較浪費,雖然地刷很好用,那個時候就包括LED都很好用,但唯一一個就是最早的時候網格非常多,當時開使用一些自己創建的一些地形,地形模型去在場景擺放,擺放過程中發現他沒有貼圖混合功能,然後我當時就是有分析U3D的系統,自己去開發了一個BlendShader還有地表混合着色器,我們的植被是可以刷的,樹幹地表石頭都可以採取Blend繪製,然後整個模型只有一個,網格數也是非常稀少的。


我以前去做一些遊戲邏輯和人工智能,大家現在都知道大家都在寫腳本,但基本上我當時也做過開發,比如一些內存加密等等,但是依然解決不了就開發的時候很多漏洞和調試問題,尤其是人工智能這一塊,我想實現一個流程在引擎中,那個時候Animator出來了,利用這個狀態圖實現有線狀態機,這些狀態機的腳本都在本地裏面存着,我只需要更新服務器上的小怪的AI,也是可以的。


另外是代碼安全的問題,就是現在因爲大家都知道很多的我們開發一些遊戲發佈出去,經常會有反BA的工具把我們反BA掉,當時也是發了很多文檔,最後找到Mono虛擬機的原碼,同樣開發DLL也進行了重新編譯,基本上可以進行加密,最後發佈到Application中。



目前現在開始用另外的方法來做,這是比較老的一個方法,另外兼容和適配,最早做遊戲的時候還是,爲了覆蓋大部分的安卓機型,需要做一個很複雜的兼容適配,發現比任何代碼和算法都解決不了多機型適配問題,那個時候開使用大數據,將所有的機型配置分級別,對他們所用的配置,數據的話會直接存到服務器端,第一次登陸打開遊戲的時候,會把機型發送到服務器上,服務器根據我本地的配置在服務器尋找相關的配置資源,遊戲打開的時候自動的幫玩家適配好,根據機型最優化的表現方式。

希望大家在目前的話VR還是一個起步階段,我們還是非常缺內容的平臺,希望更多的開發者加入VR開發,我們也希望能幫助開發者一起去創造一箇中國VR互聯網的環境。謝謝大家。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章