遊戲中通常有大量資源,如網格、材質、紋理、動畫、着色器程式和音樂等,遊戲引擎作為做遊戲的工具,自然要提供良好的資源管理,讓遊戲開發者用最簡單的方式使用資源。遊戲引擎的資源管理包括兩大部分:離線資源管理和運作時資源管理。我這僅對前者進行簡要介紹,并結合Unity3D進行分析。
資源創作與導出
遊戲中的資源由各種數字内容創作工具(DCC, digital content creation)進行創作,如:
- 三維模型:3ds Max,Maya等;
- 紋理:Photoshop等;
- 音樂:Sound Forge等;
- ………………
DCC往往支援多種導出格式,如:
- 3ds Max:3DS、AI、DDF、DEM、DWG、DXF™、HTR、FBX、IAM、IGES、IPT、LP、LS、MTL、OBJ等;
- Photoshop:PSD、TIFF、EPS、PCX、GIF、JPEG、PNG、PICT、TGA等;
- ………………
遊戲引擎一般會支援指定DDC的部分導出格式,例如Unity3D支援3ds Max導出的FBX格式;或者針對特定資源創作工具編寫導出插件,例如OGRE有多種三維模組化軟體的 導出插件 。 雖然基本上所有DCC都支援多種導出格式,但是很多情況下這些格式都不适合遊戲引擎,因為
- 導出的内容過于複雜,遊戲中隻用到其部分資料,而遊戲往往對性能的要求比較苛刻,是以需要去除備援資料;
- 許多DCC導出的格式讀取比較慢,而且還有一些是封閉格式導緻引擎無法讀取。
是以,在DCC導出資源後,需要引擎進一步處理,将資源轉換為引擎的内部格式,這種處理被稱作Asset Conditioning Pipeling。使用Unity3D的童鞋應該會發現,每次導入資源的時候都要讀條,就是在進行Asset Conditioning Pipeling;OGRE在這方面的支援不夠完善,這部分工作由自定義的導出插件完成。
資源的“編譯”與“連結”
由于導出的資源存在一些問題,需要進行一定的轉換,這個轉換被稱作Asset Conditioning Pipeling,包括2個步驟:
- 資源“編譯”
讀取單個資源的資料,将其轉換為遊戲中可以直接使用的格式(使用效率最高或較高的格式),例如重新對Mesh的頂點進行排序,或使用BC5等壓縮算法對紋理進行壓縮。這個過程與C語言的編譯有些類似,是以取名為“編譯”。當然,如果導出的資源可以直接使用,那麼可以跳過這一步。
- 資源“連結”
在遊戲中,許多資源并不是單獨使用的,例如三維模型,它引用的材質和紋理是單獨存在的資源。在上一步中,引擎對單個資源進行“編譯”,将其轉換為可以直接在遊戲中使用的格式;這個步驟将所有的資源進行“連結”,使得遊戲在運作時可以找到每個資源所依賴的所有資源,例如三維模型可以正确的找到其需要的材質和紋理。這個過程與C語言的連結有些類似,是以取名為“連結”。當然,如果導出的資源可以直接使用,那麼也可以跳過這一步。
Unity3D對這部分提供了比較完善的支援,是以隻需要導出引擎所支援的标準資源,并放入Assets檔案夾,引擎會對其進行“編譯”和“連結”,結果就在Library檔案夾中(裡面亂七八糟的,雖然我們看不懂,但是Unity3D很喜歡);OGRE沒有提供專門的Asset Conditioning Pipeling工具,是以所有操作都在資源的導出插件中完成,沒有進行單獨的“編譯”和“連結”。
資源管理資料庫
在資源通過Asset Conditioning Pipeline之前,引擎需要存儲處理該資源的方式,一般使用metadata(中繼資料)來描述,例如指定某個紋理應該是以何種方式壓縮。引擎通過 資源資料庫來管理metadata,資源資料庫既可以簡單的使用XML檔案進行描述,也可以使用MySQL等資料庫。遊戲開發者通過引擎提供的接口實作資源的重新配置,例如在Unity3D編輯器中可以修改Mesh的壓縮方式,選擇是否優化Mesh等。
遊戲引擎的資源資料庫一般要提供如下功能:
- 建立和删除資源;
- 檢視和修改現有資源;
- 将資源移動到其他路徑;
- 支援資源的互相引用,并且在被引用資源移動路徑後,保證引用有效;
- 提供多種便捷的查找資源的方式。
使用Unity3D的童鞋可以發現,Unity3D提供了比較完善的資源管理的功能,使用起來比較輕松。
資源讀取(運作時)
在開發過程中,所有原始資源以單個檔案形式進行儲存,以友善修改,但是在遊戲運作讀取資源的時候,為了加快讀取速度,一般會将資源打包成一個或多個檔案。打包的原因很簡單,從硬碟中讀取檔案的時間中,主要由三部分組成:
- 硬碟尋道時間;
- 打開檔案的時間;
- 讀取檔案的時間。
最後一項是不可能改變了,除非使用速度更快的存儲媒體;但是将多個檔案打包成一個檔案,可以縮短前面兩項的時間。Unity3D在釋出遊戲的時候,會将資源進行打包;OGRE沒有自定義打包資源的方式,一般打包為 一個或多個ZIP檔案,或不打包資源 。
執行個體分析
Unity3D
拷貝Unity3D工程的時候,一定要拷貝“Assets”、“Library”和“ProjectSettings”檔案夾。資源都在“Assets”,設定都在“ProjectSettings”,“Library”是來打醬油的?非也!如果不拷貝“Library”,打開工程以後你一定會大吃一驚,之前的設定全沒了?!而且場景檔案裡的東西也是亂成一團!結合上文,則很容易了解這種詭異的現象,明白為什麼少不了這個“打醬油”的“Library”。
将資源放入“Assets”檔案夾,切回Unity3D,則進入Importing Assets狀态(進行Asset Conditioning Pipelining),如下圖

導入資源
在這個步驟中,Unity3D針對所有的資源生成metadata,并進行“編譯”、“連結”,轉換為遊戲可以直接使用的資源。轉換前的資源儲存在“Assets”中,轉換後的資源儲存在“Library”中,所有的資源在Inspector面闆中可以修改metadata的資料,如下圖
“Library”檔案夾
Inspector
如果使用SVN等版本控制器,需要同步所有資源及其metadata。打開Edit->Project Settings->Editor,将Mode修改為“Meta Files”(預設“Disabled”),如下圖
選擇“Meta Files”
Mode修改為“Meta Files”後,回到資源檔案夾,會發現每個資源都多了***.meta檔案,如下圖,而這些.meta檔案儲存了這些資源将如何被Asset Conditioning Pipeline處理。
帶metadata的資源檔案
現在Assets檔案夾中不僅有所有的資源,而且還有對應的metadata,“Library”徹底打醬油了,此時在拷貝工程或使用SVN同步工程時才可以忽略“Library”檔案夾。
在釋出的遊戲中,資源檔案如下圖所示。可以發現,Unity3D對資源進行了打包,以減少資源載入時間。
釋出後的遊戲資源
總的來說,從導入資源,生成metadata,“編譯”、“連結”資源,再到釋出遊戲時打包資源,Unity3D都封裝好了,以最簡單的方式提供給我們使用,極大的提高了遊戲開發者的工作效率。雖然可能第一次在用的時候隻是感覺Unity3D用的比較簡單,但它确實在背後做了很多工作,隻是我們沒注意而已。