Resources目錄的優點與痛點

本篇文章是Addressable基礎篇系列第二節,除了我們上一節《淺談Assets——Unity資源映射》提到的Unity工程的根目錄之外,Unity的Assets目錄下其實還有一個固定的文件夾,並且存在特殊的作用,但這些文件夾在新建的工程目錄下並沒有默認創建。我們先用Unity 2018.3.8建一個空工程,然後進入到Assets裏面去看看。

一、 特殊的工程目錄

先看下Unity默認空工程的目錄。如下圖:

 

1、新工程的默認目錄
在比較老的版本中,Unity創建空工程之後,就只有一個空的Assets。現在,在Assets裏默認有了一個Scenes目錄,然後裏面有一個SampleScene的默認空白場景。在Assets的平級,有一個Packages目錄,這個是2018跟隨PackagesManager一起出現的,裏面展示的是當前工程引入的Packages。不過要注意的是,這個目錄是隻讀的,不能操作。所有的改變都是通過PackagesManager的窗口進行變化。當然,你也可以手動到磁盤的對應目錄去修改它的Json文件,雖然也能達到效果,但是不推薦大家這麼做。

2、Unity的特殊目錄
雖然新工程默認給了一個Scenes的目錄,但其實這個目錄並沒有特殊意義。你可以把場景存放在任意的自定義目錄下面。

(1)Editor
第一個介紹的就是這個目錄。這個目錄是用來輔助開發的,可以是一個,也可以有很多個,可以在任意的子目錄下面。主要作用就是可以編譯Unity編輯器模式下提供的腳本和接口,用於輔助研發,創建各種資源檢查,生成工具,以及自定義Unity的工具欄,窗口欄等等。Editor目錄下的所有腳本都不會被編譯到正式發行包裏,很多很多優秀的插件都是需要通過Unity提供的編輯器下的擴展接口來實現功能擴展的。

(2)Editor Default Resources
這個需要和Editor配合使用。一個擴展面板或者工具光禿禿的也不好看,配上一些美化資源之後會讓你的插件或者工具格局更高。要注意的是,這個目錄只能是唯一的,並且只能放在Assets的根目錄下。

(3)Plugins
這個目錄是存放代碼之外的庫文件的。比如引入的第三方代碼,SDK接入的各種jar包,.a文件,.so文件.framwork文件等等,這些庫文件會在Unity編譯的時候鏈接到你的DLL裏。

(4)Resources
這個和Editor一樣,可以在Assets下的任何目錄下,並且可以有任意多份。所有Resources目錄下的文件都會直接打進一個特殊的Bundles中,並且在遊戲啓動時,會生成一個序列化映射表,並加載進內存裏。

(5)Gizmos
這個目錄其實比較簡單,就是可以輔助你在Unity的Scene視窗裏顯示一些輔助標線,圖標或者其它的標識,用來輔助開發定位資源。比如:


按鈕在Scene窗口的最右上角。要注意的是,因爲是Scene視窗的,所以Game視窗和發佈之後都不會看到。

(6)StreamingAssets
這個文件是Unity的一個重要文件。Unity發佈程序或者遊戲,資源隨包出去的時候,只有2個地方,一個就是Resources目錄,另外一個就是StreamingAssets。這個目錄的資源,文件或者任何東西,都會原封不動的複製到最終的Apk或者iOS的包內。

除了上面這些特殊目錄之外,如果是一個正常的工程,還會有很多其它導入的插件、或者自定義目錄。這裏有一篇我之前寫過的文章,用於規劃Unity的工程目錄來適配多人的、不同職能的協同合作。

地址:https://zhuanlan.zhihu.com/p/77058380


二、Resources詳解

我覺得,Resources之所以能被廣泛地使用,是因爲它的使用非常簡單,並且是同步加載。一般來說,正式的商業項目,對外發布資源的時候都是使用AssetBundles的方式進行。AssetBundles的方式有很多缺點,比如:

  • 無法直觀地看到包內的資源情況。
  • 異步加載,需要寫比較繁瑣的回調處理。
  • 調試的時候,無法通過Hierarchy直接定位到資源。
  • 使用之前需要花費時間進行打包,尤其是在開發的時候,調整資源頻繁,如果忘記打包可能導致Bug。

前面我們也說了,Unity處理資源就2種方式,Resources和AssetBundles。那麼既然AssetBundles開發期這麼不好用,大部分時候就使用Resources代替了。

那麼問題來了,使用Resources就沒問題了嘛?

1、Resources目錄的最佳實踐
在講缺點之前,先看一下Unity官方對於Resources使用的最佳實踐:
不!要!使!用!它!

不要驚訝,這就是官方的態度。出於幾點原因,Unity並不希望大家過度使用Resources,是因爲:

  • Resources內的資源會增加應用程序的啓動時間和構建時長。
  • Resources內的資源無法增量更新,這是現在手機遊戲開發的致命點。

所以官方建議,使用AssetBundles(陷入了沉思...)。

其實也不用太在意了,經過多年的開發,其實早就累積瞭解決方案。後面會稍微提一下,但是最大的解決方案還是我們這個系列的主題 Addressable Asset System。不過這是後話了,等下會講一下在沒有出這套東西的時候是怎麼解決的。

2、哪些情況我們可以使用Resources
Resources有它的致命性缺點,但是存在即合理。它還是有它的一些使用場景的,比如:

  • 某些資源是項目整個生命週期都必須要用的。
  • 有些很重要,但是卻不怎麼佔內存的。
  • 不怎麼需要變化,並且不需要進行平臺差異化處理的。
  • 用於系統啓動時候最小引導的。

另外還有一種情況就是,當你需要給老闆快速展示一些效果,或者要快速完成Demo,或者要寫一些教程、文章、分享展示方案的時候,使用Resources可以節省時間。但是要注意,一旦你決定要把既定的工程用於正式生產的時候,請一定把它用AssetBundles重寫。

3、Resources的序列化
如前文所說,構建項目的時候,所有的Resources目錄下的文件會被合併爲一個序列化文件。該文件會有自己的metadata信息和索引信息。內部用紅黑樹實現資源查找,用於索引相應的File GUID和Local ID,並且它還要記錄在序列化文件中的偏移量。

官方的實際測試數據,一個擁有10000個Assets的Resources目錄,在低端移動設備上的初始化需要5-10秒甚至更長。但其實,這些Assets並不會在一開始就全部用到。

4、開發中的替代方案
前面把Resources和AssetBundles不便的地方都說了一遍,那麼有沒有一種方案,既可以在開發時候快速加載,又沒有Resources那些缺點呢?有的,其實就是AssetDatabase。

這是一個Unity在編輯器模式下的資源加載類,它提供了常規資源的Create、Delete、Save、Load等常用接口,並且是同步加載。所以我們只需要自己寫一個資源管理類,用宏區分Editor模式,在Editor直接使用AssetDatabase進行資源加載,然後模擬一個異步回調,讓它看起來跟AssetBundles 加載流程相似,然後在非Editor模式下,調用正常的AssetBundles加載就可以了。

雖然這個資源管理器寫起來會很煩,但是一旦流程調試對了,後面就不用再管了。至於AssetDatabase也不展開講了,找了一個比較詳細的文檔,大家可以參考:https://www.jianshu.com/p/2cae2f082f66

除了AssetDatabase這個方案之外,另外一個就是這系列文章的主題Addressable Asset System了。這個是2018之後官方引入的,把我剛纔說的那些做了封裝和組合,並且解決了開發中對資源管理的一些痛點,不過再講這個之前呢,還需要再插入一章內容,講解一下AssetBundles的系統知識。

封面圖來源於網絡


這是侑虎科技第663篇文章,感謝作者放牛的星星供稿。歡迎轉發分享,未經作者授權請勿轉載。如果您有任何獨到的見解或者發現也歡迎聯繫我們,一起探討。(QQ羣:793972859)

作者主頁:https://www.zhihu.com/people/niuxingxing,作者也是U Sparkle活動參與者,UWA歡迎更多開發朋友加入U Sparkle開發者計劃,這個舞臺有你更精彩!

發佈了406 篇原創文章 · 獲贊 134 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章