1. 程式人生 > >Unity中專案資源管理的一些經驗與總結

Unity中專案資源管理的一些經驗與總結

歡迎大家去我的小站Reset研究所坐坐:原文地址

原本想寫一下Unity中通過資源來減小遊戲中記憶體效能的文章,不過我一直採用的還是打圖集、壓資源、延遲載入等老一套,感覺不是很夠講所以就只講了一部分優化,後面一部分就來講一下Unity專案中的資源管理吧。Unity的專案管理可以說在不同的公司中會很不相同,每一個公司可能都會有自己的一套流程,但是核心的思想其實確實也是一樣的。

鄙人才疏學淺,如果有所疏漏或者有錯誤的地方還希望 多多指正。

貼圖優化

貼圖資源是遊戲當中消耗最大的資源,貼圖資源的管理直接影響到整個遊戲記憶體的效能。

  • 使用圖集:使用圖集能夠很好解決drawcall過高的問題。Unity中的SpritePacket能夠很好地幫助我們建立圖集,而且支援剝離透明通道,幫助我們更好地壓縮圖集檔案,減少資源記憶體的佔用。在雨鬆MOMO的部落格當中對其也有比較詳細的講解:UGUI研究院之SpritePacker打包引數(四)
  • 對於通用紋理,儘可能的使用九宮格。如果用大塊的紋理則會佔用較大的記憶體空間。而針對對稱紋理則可以使用shader或者Scale翻轉等方法來重複利用以減小記憶體消耗。
    九宮格
  • 對於有較明顯的遠近關係的物體,我們可以使用Mipmap來減少執行時渲染的頻寬。如果沒有這種需要的話(例如2D場景和UI)則需要及時關閉,因為會佔用一定的記憶體空間。Unity中也有Mipmap檢視提供給我們進行檢視:
    Mipmap
  • 通過設定“MaxSize”來限制圖片的大小,一般來說我們應該講圖片縮小到肉眼剛好看不出壓縮的程度。圖片不要超過2048.
  • “Format”則表示壓縮的方式,不同的平臺我們應該用不同的壓縮方式來進行壓縮。例如:安卓使用ETC而IOS則使用PVRTC。
  • 一般情況下我們需要關閉圖片的Read&Write選項,否則記憶體會大一倍。除非我們對影象需要進行讀寫操作。
  • 針對顏色範圍不大的素材,我們可以降低圖片的色階以減小圖片的大小。

模型優化

  • 保證不可讀寫。
  • 將沒有動畫的模型上的動畫指令碼去除,否則會消耗cpu。
  • 多個角色分享一套rig,可以解決資源。
  • 使用MeshCompression
  • 模型莫名期末有很多particle view*物體。在3DMAX中當你按下6時候,會彈出particle view視窗。同時會生成一個多餘的particle view物體(這個物體在大綱中是找不到的,但當使用Ctrl+A的時候,他就會被選到,而且這個物體會佔用一定的檔案空間),在匯出時particle view會嚴重擾亂物體的軸心。決方法很簡單,只要在max匯出之前,按下f11鍵,進入max的指令碼編輯器,輸入delete $’particle view*’,回車,此時下一行會提示有幾個particle view被刪除了。看到這個數字即可以放心匯出了。
  • 當動畫播放出現褶皺、破損、奇葩的時候,估計是點受骨骼影響太多了,U3D設定中一個點最多隻能受4個骨骼影響。
  • 在UI中最好不要使用Mesh特效,否則無法判斷深度。除非使用RendererTexture來適應,儘可能讓美術用別的方案來替代。

音訊優化

  • 在IOS上使用Mp3 Compression,而在安卓上使用Vorbis Compression
  • 在移動遊戲中使用Force Mono
  • 位元率調的儘可能低

文字檔案優化

  • 解析文字是比較慢的。
  • 將文字轉成二進位制檔案,可以有效提高讀寫速度。
  • 將文字分成小塊,只讀取需要的部分。讀入之後如有必要則Cache起來。
  • 利用執行緒進行多執行緒讀取。

AssetBundle管理

目前市面上的大多數遊戲都要涉及到熱更新,從Unity5.0開始,簡化的API讓AssetBundle的打包似乎不再是一件困難的工作,但是想要管理好AssetBundle的關係卻並不是那麼容易的一件事。

在遊戲中載入資源我使用過兩種做法,都需要自己對載入方式進行封裝,通過多型來靈活載入工程內或者熱更的資源:

  1. 一種是講所有需要載入的資源,例如prefab、文字等等放入到Resources下面(儘可能減少資源否則會影響啟動速度),而依賴的資源放在別的資料夾下,熱更的時候將資源載入到沙盒目錄下。在資源載入的時候,首先對沙盒目錄進行檢查,若有的話,則使用熱更資源,否則就載入Resource下的資源。優點是在工程內不需要打包,而缺點是由於沒有打包,導致在最後出包的時候打包緩慢。

  2. 而另一種是將所有的資源打成AssetBundle放入StreamingAssets下,熱更的時候同樣十八AssetBundle下載到沙盒目錄下。資源載入的時候,首先對沙盒目錄進行檢查,若有的話使用熱更資源,否則就載入StreamingAssets下的資源。在載入的時候需要提供資源名和包名,在編輯器下可以通過AssetDatabase來直接從編輯器中載入資源,通過將場景加入到BuildSetting中來載入場景,避免每次進行修改的時候都需要重新打AssetBundle。這種方法在最後出包的時候比較快,在最終確定下資源正確性的時候構建AssetBundle。

  • 通過延遲載入來對AssetBundle進行載入,在一般的使用場景下,我們並不需要將所有的AssetBundle進行載入。在遊戲中,我們將建立一張常用的Bundle列表,用於進入場景時載入該場景中的常駐資源。而不一定會出現的資源則在需要的時候進行即時載入,並且放入Bundle池中隨時準備取用,當Bundle閒置達到一定的時間後對其進行自動的解除安裝,這取決於該Bundle的使用頻度。在切換場景之後解除安裝該場景的常用Bundle而去載入另一個場景的常用Bundle。
  • 要注意Bundle的細粒度,如果Bundle的細粒度超過一定數量的話必然會引起熱更包體積過大,玩家的更新需要下載更多的資源包,而在場景中也需要載入更多原本並不被需要的資源,而過小細粒度則會造成場景載入的緩慢,給管理上也會增加難度。所以適當的細粒度在AssetBundle的分包中也非常重要。
  • 將公用的資源單獨打成包:如果一個資源本身沒有標記任何的Bundle包,而被許多別的Bundle包引用則會被打入每一個引用它的Bundle中,造成包體積的膨脹。例如Shader這樣的材質就很有必要單獨打成一個包用作公用,否則包體積和遊戲記憶體佔用會變成一個大問題。
  • 當手機的容量較小時,可以通過WWW.LoadFromCacheOrDownload來進行載入,而不必擔心記憶體不足的問題。
  • 在將程式碼打包到Prefab的時候對於Component要用動態載入的方式,考慮使用lua指令碼進行操作,或者是直接動態從程式集載入,這樣可以避免資源與程式碼不同步的情況發生。可以只對程式碼進行修改而不需要重新進行資源打包。
  • 在使用第二種方案建立專案的時候可以建立一個或者幾個資源專案,用於大量資源的打包,用於將AssetBundle打包並放入主專案中,在主專案的在打包的時候不必再對所有的AssetBundle資源進行再打包,可以大大提高打包效率,並且可以將工作流放入到資源專案當中,提高資源的迭代效率。
  • 在為資源分包的時候可以按照資料夾來進行區分,以便於管理。
  • 當在一個地方需要用到包中的一小個資源,例如一個2048*2048圖集中的一個小icon。拷貝一份,並且放入到目前需要使用的包中,避免由於小的資源需求而引入大記憶體消耗。

資源工作流管理

作為程式,我們在資源上面花的精力自然是越少越好,但是如果沒有好的工具鏈,好的流程,我們必定將會困在永遠做不完的資源管理中。美術發過來的max檔案或許需要經過你的匯出、匯入到Unity、拖成預製體、掛動畫、掛碰撞盒等等的操作之後才能成為一個真正可用的資源。這個時候一個好的工具顯得格外重要。

  • uTomate,用於管理流程的Unity外掛,我們可以通過簡單的節點連線來對我們的資源進行一系列操作的配置。除此之外,我們還可以用它來做一鍵打包等功能。
  • Defaulter – Custom Importer Defaults ,用於管理資源的匯入統一化,通過路徑來決定其中資源的格式,例如:貼圖對應著的MaxSize、Format、Read&Write等等,還支援其他很多的資源,通過這個我們不再需要對每一個匯入的資源進行手動的設定了,由於其開源的有點,我們也可以根據我們自己的需要進行優化。由於作者不再維護了,所以我們或許需要自己來進行編寫。
  • 熟悉一些簡單的程式指令碼,例如maxscript或者是ps中的ExtendScript ToolkitCS6。我就曾經自己寫過一個自動切圖的小外掛,不過效率不是很行,但是語言本身並不難學,能給美術和程式自己帶來很多方便,通過C#對命令列呼叫的方式整合到Unity中,相信整個工作會輕鬆不少。
  • 利用Jenkins或者Hudson進行持續整合。人肉整合是對人力與資源的一種浪費,極其容易出現錯誤,而本地打包則大大佔用了程式設計師的本地頻寬,讓程式設計師無法繼續進行工。而通過配置Jenkins來自動實現可引數化的、穩健的、可持續的整合,專案組可以集中更多的力量來進行產品的迭代。
  • 使用Spine或者Unity Anima2D來製作2D動畫,可以事倍功半。
  • 當然最靠譜的還是自己用C#來寫工具,雖然會花一些時間,但是磨刀不誤砍柴工,花一天時間寫工具,今後的幾個月當中可能會減少你好幾天的工作量。好工具所帶來的生產力可能大大超出你的想象。
    資源的工作流除了用於生成資源,對於資源的管理也是非常的重要。

推薦的方式是程式使用更加靈活的git來進行管理,有條件的可以自己做一個gitlab伺服器用於存放程式碼。而美術則使用區域網SVN進行美術資源的管理,程式可以將部分直接可用的美術資源直接鏈入專案當中,其他的則是通過上述提到的工作流工具來進行批量處理。

當然還有很多其他的優秀外掛與工具可以幫助我們來優化工作流,如果大家也有好的工具的話歡迎分享交流~