1. 程式人生 > >unity3D學習筆記之九 資源管理

unity3D學習筆記之九 資源管理

  • 遊戲中通常有大量資源,如網格、材質、紋理、動畫、著色器程式和音樂等,遊戲引擎作為做遊戲的工具,自然要提供良好的資源管理,讓遊戲開發者用最簡單的方式使用資源。遊戲引擎的資源管理包括兩大部分:離線資源管理和執行時資源管理。本文僅對前者進行簡要介紹,並結合Unity3D和OGRE進行分析。

    資源創作與匯出

      遊戲中的資源由各種數字內容創作工具(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用的比較簡單,但它確實在背後做了很多工作,只是我們沒注意而已。

    OGRE