細談unity資源管理的設計

 

轉載請標明出處:http://www.mrxneb.tw/zblade/

 

一、概要

本文主要說說Unity是如何管理的,基于何種方式,基于這種管理方式,又該如何規劃資源管理,以及構建bundle,是后面需要詳細討論的。

二、Unity的資源管理方式

2.1 資源分類

unity項目中的資源,大體上可以分為外部導入資源和內部生成資源兩種類型。
外部導入資源: 美術生成的大部分資源,都是外部帶入資源,模型,貼圖,UI用圖,基本是美術工具生成后,導入到工程中的。
內部生成資源: 部分美術生成資源,例如材質,shader,特效,場景等,屬于基于Unity引擎來制作生成的,此外各種prefab(UI/角色等),以及代碼腳本(c#為主),也屬于Unity的內部生成資源。

2.2 資源的存儲方式

在資源導入到unity工程后,會以各種方式進行轉換存儲,主要有以下幾種:

2.2.1 腳本類資源

對于工程中的腳本類資源,主要分為plugin和非plugin兩類。

  • plugin類:在plugin中引用的dll, 屬于自己生成相關的dll,在最終構建游戲包的時候,被打入到相關游戲包中:      
  • 非plugin類:unity會構建成4個基本的dll, 構建的順序為:
    • Assembly-CSharp-firstpass: standard assets/Pro standard assets/plugins 中的腳本
    • Assembly-CSharp-Editor-firstpass: editor scripts in standard assets/Pro standard assets/plugins 這個dll不會被打入到游戲包中,屬于編輯器下特有的dll
    • Assembly-CSharp: all other scripts that not inside editor 主體游戲邏輯的dll
    • Assembly-CSharp-Editor: all remaing scripts inside editor 這個dll也不會被打入到游戲包中,編輯器中特有的dll

所有最終構建到游戲包中的dll,主要分為:

  • Assembly-CSharp.dll/Assembly-CSharp-firstpass.dll 這2個主要游戲邏輯dll
  • 引擎dll和插件引用的dll

2.2.2 美術類資源

美術類資源,分為外部導入和內部生成兩個大類

  • 外部導入類: 場景/模型/貼圖 都可以外部導入
    • 繼承自AssetPostprocesser后,可以對導入的貼圖,材質,模型,場景,均執行相關的修改
  • 內部生成類: shader/材質/prefab/場景 均可以內部生成美術資源的貼圖資源和特效資源,屬于重點關注對象,后面會細談這幾個資源的管理
    • 修改操作同上

2.2.3 meta文件

工程資源劃分好后,如何對這些資源進行管理? 不同的引擎有不同的管理方式,那么unity中是如何管理的?
這兒管理分為2個步驟:序列化和meta文件的生成

2.2.3.1 unity的序列化

工程中的資源,要存儲到本地磁盤,那么就會通過引擎進行一步序列化的操作,序列化的實質,就是將資源對象按照一定的順序轉換成二進制文件。

2.2.3.2 meta文件的生成

在完成序列化后,unity會對應的為該文件生成一份meta文件,這份meta文件會跟隨該文件一直存在,如果刪除該資源文件,其對應的meta文件也會被引擎自動刪除。
meta文件的主要構成:

  • 文件的guid: 這個文件的全工程中的唯一索引id,基于該id,可以對應的查找到該文件。guid的生成本質,就是基于文件的路徑來進行轉換生成的,同理,如果多個工程合并的時候出現guid沖突,可以自己重新生成一份guid,相關鏈接: https://gist.github.com/ZimM-LostPolygon/7e2f8a3e5a1be183ac19

  • 文件的導入設置:

    • 對于一般的文件,導入設置都比較簡單腳本類叫MonoImporter, 資源類叫NativeFormatImporter
    • 貼圖屬于需要重點關注的類型,其導入類型叫TextureImporter,里面詳細的列出對該貼圖的各種壓縮格式,mipmaps, 類型,uv,貼圖大小等等詳細的設置信息

2.2.4 基于meta文件和序列化的資源管理

除了meta文件的guid,unity還會為每個資源生成一份文件id,也就是fileID, 不過現在fileID已經不再保留在meta文件中了,保留到文件的序列化文件中了,對于該資源,還會有一份localID, 這個localID, 對應的就是在一個資源中包含多個子資源的時候,定位每個子資源所用:  

那么序列化是如何與guid/fileID關聯的?
在unity工程內部,如果給資源添加其他資源的引用,例如加一個腳本,拖拽一個外部引用,那么就會觸發一次序列化操作,序列化操作的時候,就會將引用的資源的fileID和guid都序列化下來,這樣在反序列化的時候,就會基于fileID和guid來反向找到依賴的資源,從而加載進來。   

這個過程,在Unity中,就是一個裝載的過程,多說一句,如果一個資源依賴的其他資源越多,那么這個裝載過程就會越耗時,所以在打開一個很大的UI的時候,有一部分的時間是消耗在裝載UI上各個組件上的。

三、總結

基于前文,可以對整個unity的資源管理有一個初步的認識,基于meta文件和序列化操作,可以管理工程中的資源,同時也能管理好各個資源的互相引用,那么基于這樣的設計,在構建bundle的時候,是可以進行相關的設計和實現的。

posted @ 2019-06-26 11:48 zblade 閱讀(...) 評論(...) 編輯 收藏
内部期期公开一波中特