我研究SpriteAtlas的Include in Build的作用將近一天了,實在是頭大,然後也不知不覺把丟失的英語給撿起來了。。。
首先官方的介紹:
https://docs.unity3d.com/Manual/SpriteAtlasDistribution.html
中文意思:不勾選Include in Build時,在發佈的構建(項目)時,圖集是不會包含在內的(assetbundle裏依舊會有);在運行時也不會自動加載(我很想吐槽,運行時這麼多種情況,到底時哪種情況?)
個人嘗試:
unity版本:2019.2.21f個人版
注意:
圖集能夠正常在打包後使用,首先需要在project setting如下圖設置
對圖集進行Include in Build勾選狀態的改變時,需要對其關聯的所有ab包全部重新打一遍(後面會分析,爲啥需要重新打一遍)。
例如從未勾選到勾選狀態,重新打一遍ab包,否則在editor和發佈的項目中,需要顯示的圖片依舊時空白狀態。然後做資源前後對比,勾選時比不勾選時,用到圖集的紋理的ab包(非包含spriteatlas的ab包)的信息會增加。
正式開始介紹:
以我測試文件爲例:圖集所在ab包名爲atlastest,引用了圖集內紋理的ab包爲assetbundlecontent
對於Include in Build的勾選前後文件比較,assetbundlecontent與atlastest的大小均有改變。
未勾選時:
用assetbundle extrator查看內部的情況
勾選後(記得刪除原來的ab包重新打,否則assetbundlecontent不會改變的)
經對比atlastest的大小和佔用空間時不變的,但是atlastest文件本身是有改變的(懷疑是某個bool值變更了而已,勾選與不勾選的區別),用assetbundle extrator對比ab內的資源,是一樣的
然後assetbundlecontent的比較,兩者大小不一樣(61676與62087),多了409bytes。assetbundle extrator比較,基本是一樣的,除了一個assetbundlecontent,include in build 的情況爲480bytes,未勾選時爲452bytes。說明勾選與未勾選時,對於依賴這個圖集的ab包是有影響的。
實際發佈項目(build and run)
不勾選include in build時,圖片全部是白的;勾選include in build時,圖片是可以顯示的。
回到官方的解釋,官方說,其實不影響ab包,而是在發佈項目的時候會有影響,那麼果真如此麼?
再做個試驗:
未勾選include時發佈應用(pc版 build and run),運行查看,確實沒顯示圖片。然後我們不重新發布應用,而是替換應用中的assetbundlecontent,assetbundlecontent.manifest,atlastest,atlastest.manifest爲未勾選include時生成的ab包,結果是:md
圖片就可以正常顯示了!!!
所以,官方文檔上的解釋你不是在騙我麼,搞笑呢(我通過控制變量,證明include in build與工程發佈沒有關係,與ab包纔是有關係啊)
那麼再進一步考證,可能這個assetbundle使用的圖集不是atlastest內的圖集,我把atlastest刪了,再次運行,圖片變白了(說明確實引用了)
而經過上述比較,勾選include in build實際對包體的大小的影響實在是有限(8m的圖集,勾選include in build,影響其依賴的ab包才幾百bytes),圖集上千,涉及萬個依賴的ab包,也才幾M啊(那你爲啥不夠選include in build呢)。
況且不勾選後,還需要進行late binding操作,參考:
https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlasManager-atlasRequested.html,然後需要用到圖集中的圖片時,還需要經過加載目標spriteatlas才能使用(ab包不太好根據界面加載卸載管理圖集的加載卸載啊)(經過測試,這個延遲綁定是有效的)(那你爲啥不夠選include in build呢)
那麼勾選include in build,官方提及會automatically load it,意思是自動加載圖集。那麼我的疑問是這一塊的內存是如何管理的呢,加載會自動釋放麼,需要我們手動卸載麼,會一直在內存中存在麼。這些我都沒測試,目前也不知道該如何測試。
然後通過此次試驗對於以前的貼子進行考證:
https://answer.uwa4d.com/question/5a822325847802258a06509e
經過上述測試過程,發現無論勾選不勾選include in build選項, 圖集資源(atlastest包含的相關資源),並沒有被assetbundlecontent重複包含(assetbundlecontent只有四個sprite,tree_1,tree_2,tree_3,tree_4,沒有任何texture類型的資源)
這個帖子做了一定的解釋,在Unity 2018.4.6中,Unity已經修復了這個問題:
https://www.cnblogs.com/murongxiaopifu/p/12453356.html
所以像這種還在講include in build 時會造成打包資源冗餘就是過時的(基本是uwa上的文章,md):
https://blog.uwa4d.com/archives/TechSharing_116.html
https://zhuanlan.zhihu.com/p/38341616
https://blog.csdn.net/akof1314/article/details/48376373
https://blog.csdn.net/UWA4D/article/details/82986037
(,實測,pc平臺是與app包體無關的,換ab包就可以,帖子中提到的資源雙份的情況也不存在,Unity 2018.4.6中已經修復了)
再補充一點的是:
我測試都是在pc平臺,這裏有個帖子提到在安卓真機也是我同樣的情況,https://www.520mwx.com/view/9654(這個帖子引用的這裏的討論https://www.litefeel.com/unity-2017-new-sprite-atlas/#comment-28099)
(裏面的人也犯了錯,在進行include in build 操作後,沒有重新打依賴這個圖集的ab包。最好刪除所有的再重新打ab包!!!)
然後就是
https://blog.csdn.net/u013052238/article/details/103293794
這個帖子提到的,勾選include in build ,如果找不到正確資源會觸發SpriteAtlasManager.atlasRequested,這個試驗還沒做
總結:
在2019.2.21f版本測試:
include in build跟應用發佈沒有關係,只跟ab包的發佈有關。用勾選了include in build的ab包替換未勾選的,就可以正常顯示
include in build勾選後不會造成資源冗餘,但會造成依賴此圖集的ab包的會多出額外的信息(多出的內容無法查詢,暫時也找不到資料),這些額外的信息佔的空間幾乎忽略不計,成百上千上萬後,也不會對資源大小產生質的影響。
疑問:
include in build勾選後,圖片是可以正常顯示的,肯定是在ab包裏的asset實例化時,圖片實例化前,對圖集進行加載了,這部分圖集的內存管理是怎麼樣的?是否時常駐內存?是否需要手動管理?如果常駐內存,那麼每次加載別的ab包,將其對應的圖集也加載到內存並常駐了,這豈不是很糟糕?這些疑問可以參看這個下篇文章
遊戲開發unity資源管理系列:SpriteAtlas的Include in Build的作用探究(下)
最後,因爲我只對單個圖集進行了研究,想必多個圖集估計情況也是一樣的。我不知道我的實驗過程是否一定是準確的,然後看不到unity源碼(非常不喜歡unity的這一點,但凡有疑問,只能靠官方,靠黑盒測試),不知道勾選Include in Build的真正影響哪些流程,歡迎大家在評論區留言討論