天天看點

unity3d引擎的資源管理機制

遊戲中通常有大量資源,如網格、材質、紋理、動畫、着色器程式和音樂等,遊戲引擎作為做遊戲的工具,自然要提供良好的資源管理,讓遊戲開發者用最簡單的方式使用資源。遊戲引擎的資源管理包括兩大部分:離線資源管理和運作時資源管理。我這僅對前者進行簡要介紹,并結合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提供了比較完善的資源管理的功能,使用起來比較輕松。

資源讀取(運作時)

在開發過程中,所有原始資源以單個檔案形式進行儲存,以友善修改,但是在遊戲運作讀取資源的時候,為了加快讀取速度,一般會将資源打包成一個或多個檔案。打包的原因很簡單,從硬碟中讀取檔案的時間中,主要由三部分組成:

  1. 硬碟尋道時間;
  2. 打開檔案的時間;
  3. 讀取檔案的時間。

最後一項是不可能改變了,除非使用速度更快的存儲媒體;但是将多個檔案打包成一個檔案,可以縮短前面兩項的時間。Unity3D在釋出遊戲的時候,會将資源進行打包;OGRE沒有自定義打包資源的方式,一般打包為 一個或多個ZIP檔案,或不打包資源 。

執行個體分析

Unity3D

拷貝Unity3D工程的時候,一定要拷貝“Assets”、“Library”和“ProjectSettings”檔案夾。資源都在“Assets”,設定都在“ProjectSettings”,“Library”是來打醬油的?非也!如果不拷貝“Library”,打開工程以後你一定會大吃一驚,之前的設定全沒了?!而且場景檔案裡的東西也是亂成一團!結合上文,則很容易了解這種詭異的現象,明白為什麼少不了這個“打醬油”的“Library”。

将資源放入“Assets”檔案夾,切回Unity3D,則進入Importing Assets狀态(進行Asset Conditioning Pipelining),如下圖

unity3d引擎的資源管理機制

導入資源

在這個步驟中,Unity3D針對所有的資源生成metadata,并進行“編譯”、“連結”,轉換為遊戲可以直接使用的資源。轉換前的資源儲存在“Assets”中,轉換後的資源儲存在“Library”中,所有的資源在Inspector面闆中可以修改metadata的資料,如下圖

unity3d引擎的資源管理機制

“Library”檔案夾

unity3d引擎的資源管理機制

Inspector

如果使用SVN等版本控制器,需要同步所有資源及其metadata。打開Edit->Project Settings->Editor,将Mode修改為“Meta Files”(預設“Disabled”),如下圖

unity3d引擎的資源管理機制

選擇“Meta Files”

Mode修改為“Meta Files”後,回到資源檔案夾,會發現每個資源都多了***.meta檔案,如下圖,而這些.meta檔案儲存了這些資源将如何被Asset Conditioning Pipeline處理。

unity3d引擎的資源管理機制

帶metadata的資源檔案

現在Assets檔案夾中不僅有所有的資源,而且還有對應的metadata,“Library”徹底打醬油了,此時在拷貝工程或使用SVN同步工程時才可以忽略“Library”檔案夾。

在釋出的遊戲中,資源檔案如下圖所示。可以發現,Unity3D對資源進行了打包,以減少資源載入時間。

unity3d引擎的資源管理機制

釋出後的遊戲資源

總的來說,從導入資源,生成metadata,“編譯”、“連結”資源,再到釋出遊戲時打包資源,Unity3D都封裝好了,以最簡單的方式提供給我們使用,極大的提高了遊戲開發者的工作效率。雖然可能第一次在用的時候隻是感覺Unity3D用的比較簡單,但它确實在背後做了很多工作,隻是我們沒注意而已。

繼續閱讀