這是一個關(guān)于Unity游戲包體優(yōu)化方案的全面介紹
打包規(guī)則
- 所有非editor下的托管代碼會編譯為dll葵硕,dll會進(jìn)入包體坪郭。
- 所有StreamingAssets下的文件會被復(fù)制到包體坯钦。
- 所有Resource下的資源會被無條件打包。
- 所有加入到構(gòu)建中的場景以及他們所引用的所有資源都會進(jìn)入包體迹淌,如場景使用了模型顷牌,模型使用了材質(zhì),材質(zhì)使用了shader和貼圖返劲,這些資源都被引用了玲昧。
- 其他一些閃屏,icon等
- plugin下的本地庫等會視情況打包
Unity文檔中的優(yōu)化方案
先看一下Unity文檔中對于優(yōu)化iOS包體的建議:
http://docs.unity3d.com/Manual/iphone-playerSizeOptimization.html
文檔最后最后列出清單如下:
- 最小化資源(assets)篮绿,對貼圖使用PVRTC壓縮孵延,并且盡可能減小分辨率
- 設(shè)置striping level 為 use micro mscorlib
- 設(shè)置 script call optimization 為 Fast but no excetions
- 不要在代碼中使用任何System.dll或System.Xml中的東西,這些庫和micro mscorlib不兼容
- 移除不必要的代碼依賴
- 設(shè)置API兼容等級為.net2.0 subset,注意.net2.0 subset對一些庫有限制和兼容性問題
- 不要使用JS數(shù)組
- 避免泛型容器使用值類型亲配,包括結(jié)構(gòu)體
可以看出來優(yōu)化大小主要有以下幾個方面尘应、資源大小,代碼優(yōu)化弃榨,Unity設(shè)置菩收。
Unity設(shè)置
先說Unity設(shè)置,因為這個最簡單鲸睛,功能是固定的娜饵,使用情況也是固定的,基本只要程序正常執(zhí)行官辈,選擇包最小的設(shè)置即可箱舞。
Striping Level 裁剪等級
裁剪等級設(shè)置的越小遍坟,代碼裁剪的越多,包體也就越小晴股,但是會帶來一些限制愿伴,所以酌情使用即可。具體可參考Unity文檔电湘。
.net subset .net子集
.net中常用功能均在.net子集中隔节,如果你只使用了這些功能,就可以選用.net子集寂呛,.net子集比.net2.0大約小1M-2M
script call optimization (iOS)(不詳)
根據(jù)文檔怎诫,選擇Fast but no exceptions會減少大小,但具體減少多少未測試贷痪,且選擇這項從字面理解應(yīng)該是出現(xiàn)異常應(yīng)用會閃退幻妓。
削減架構(gòu)支持
比如安卓如果只打算支持armv7設(shè)備,則不要選擇x86或arm+x86劫拢,iOS同理(bitcode待測試)
代碼優(yōu)化
代碼優(yōu)化能帶來的效果有限肉津,簡單說下.
移除不必要的代碼依賴
如果你的代碼中存在一些大型庫的源碼或dll,如json.net舱沧,但卻并沒有用到妹沙,應(yīng)該將其移除,這些代碼或dll可能占用比較大的空間(json.net的dll占用1M)熟吏,如果經(jīng)過il2cpp編譯則可能更大初烘。
JS數(shù)組問題(不詳,一般也不會用到JS腳本)
文檔中提到分俯,具體不詳
避免值類型作為泛型(不詳,且難以避免)
文檔中提到哆料,具體不詳
資源優(yōu)化
資源占用大小最多缸剪,資源類型和優(yōu)化方式也非常多,具體選擇優(yōu)化方案也需要根據(jù)實際情況和經(jīng)驗來判斷东亦。
Assets與StreamingAssets的區(qū)別
要理清資源優(yōu)化的關(guān)鍵杏节,先搞清Assets與StreamingAssets的區(qū)別
StreamingAssets下的文件,在打包時會直接復(fù)制進(jìn)包里典阵,只能通過IO或者WWW讀取成Assets之后才能使用
Assets是一般的資源奋渔,比如拖拽在腳本上的引用的物體,圖片壮啊,聲音等嫉鲸,以及放在Resources下的文件。直接訪問代碼的引用或者Resources.load使用歹啼。
可以看出來Assets和StreamingAssets的第一個區(qū)別就是StreamingAssets需要IO讀取成Assets玄渗,而Assets好像Unity會在引用到時座菠,或者Resources.load時自動載到內(nèi)存中
StreamingAssets打包時是直接復(fù)制的文件,jpg還是原來的jpg,png還是原來的png藤树,文件一點也不會變浴滴,而Assets是經(jīng)過Unity處理過的,處理成了3D引擎或者硬件可以直接使用的格式岁钓,比如圖片在nvidia顯卡中以dds或dxt格式使用升略。于是,可以理解streamingAssets是磁盤上的資源屡限,assets是內(nèi)存中的資源品嚣,需要注意的是并非所有Assets都是內(nèi)存格式打包的。
下面將streamingAssets這類資源成為流資源囚霸,將Assets稱為內(nèi)存資源腰根。
圖片
圖片是游戲中使用最多的資源,使用方式繁多拓型,因此將會花大篇幅介紹優(yōu)化理論和技巧额嘿。
有了以上理論就可以解釋Unity的Inspector圖片預(yù)覽中顯示的大小和磁盤中文件的大小不一致了,預(yù)覽窗口顯示的是內(nèi)存格式劣挫,所以格式和大小都不一樣册养。
圖片資源在Unity中以內(nèi)存資源打包,空間占用大小只和尺寸和格式有關(guān)压固,所以你在外部無論如何壓縮圖片質(zhì)量球拦,圖片大小,只要不改變內(nèi)存大小和內(nèi)存格式帐我,那么打包大小始終不變坎炼。
閱讀下面之前,請先閱讀Unity文檔中關(guān)于圖片導(dǎo)入的部分
http://docs.unity3d.com/Manual/class-TextureImporter.html
圖片內(nèi)存尺寸
通常為了GPU性能3D貼圖資源最好使用2的n次冪拦键,普通2D資源為了使用方便可以沒有這個要求谣光,圖片尺寸優(yōu)化只需要在質(zhì)量可以接受情況下使用越小的越好,直接在Unity中調(diào)節(jié)max size即可芬为。
圖片內(nèi)存格式
顯卡能使用的只能是內(nèi)存格式萄金,Unity中的內(nèi)存格式分為了3類,compressed,16bit,trueColor媚朦。
關(guān)于Alpha通道氧敢,Alpha通道是圖片通道中的一個,通常表示透明询张,但并不一定表示透明孙乖,如果一張圖片有Alpha通道,或者有透明像素,那么這張圖片就帶有Alpha通道的圆。
TrueColor
trueColor,真彩色鼓拧,顏色值最多,質(zhì)量最好越妈,大小最大季俩,一般只用在追求美術(shù)質(zhì)量的2D圖片上。
- RGB24bit 不帶A通道的圖片格式
- Alpha8bit 只帶有Alpha通道信息
- RGBA32bit 同時帶有RGBA通道
- ARGB32bit 同時帶有RGBA通道梅掠,與RGBA不同處不詳
帶有通道信息越少的格式酌住,自然同樣尺寸下,大小更小阎抒,所以如果一張圖片沒有透明或者不需要alpha通道酪我,則不要保留alpha通道或透明像素,對于沒有alpha的圖片且叁,Unity會自動選擇沒有alpha的格式都哭,能夠節(jié)約1/4的大小。
16bit
16bit,只包含16位色逞带,因為顏色較少欺矫,一些漸變會出現(xiàn)過度不均勻,質(zhì)量較差展氓,大小比truecolor小穆趴。一般用于16位色質(zhì)量可接受的圖片上,或者需要alpha通道的3D貼圖上遇汞。
16bit格式包含rgb16bit,rgba16bit,argb16bit,所包含的通道按照以上名字規(guī)律未妹,需要注意的是格式大小只和bit數(shù)有關(guān),也就是說rgb16bit,argb16bit雖然通道不一樣空入,但都是16bit络它,所以大小一樣,但argb16bit顏色更少歪赢,質(zhì)量也越差酪耕,所以在重復(fù)一遍,不需要透明就不要保留alpha轨淌,透明不僅帶來空間增大,質(zhì)量也會變差看尼。
Compressed
壓縮格式递鹉,根據(jù)顯卡需要的格式進(jìn)行壓縮,如iOS設(shè)備使用PowerVR處理器藏斩,則適合的貼圖格式是PVRTC等躏结,Android手機(jī)根據(jù)芯片不同有ETC,ATC狰域,DXT媳拴,PVRTC等黄橘,但一般不會根據(jù)具體的手機(jī)打不同的包,所以一般選擇ETC屈溉,需要注意最好不要手動選擇壓縮格式塞关,應(yīng)該選擇auto Compress,Unity會自動選擇最適合該平臺的格式子巾。如果選錯格式帆赢,那么在運行時會對貼圖進(jìn)行轉(zhuǎn)碼,大大拉大加載時間线梗。
壓縮格式的圖片大小椰于,取決于不同的格式,但一般都會比trueColor或16bit小很多仪搔,質(zhì)量一般還行瘾婿,因此是3D貼圖的首選,大部分壓縮格式要求為2的n次冪烤咧,且大部分壓縮格式不支持alpha或者支持alpha但效果不好偏陪。部分2D圖片使用起來會稍微麻煩,比如強(qiáng)制為2的n次冪時sprite不能用髓削。
Mipmap
有關(guān)mipmap的詳細(xì)介紹可以參考https://en.wikipedia.org/wiki/Mipmap
竹挡,簡單的說mipmap是為了優(yōu)化3D中的顯存占用和顯示效果的,開啟這項圖片增大33%立膛,且相機(jī)距離較遠(yuǎn)時圖片會變糊揪罕,因此,2D圖片不能開啟這項宝泵,3D中一般的貼圖需要開啟好啰,其他酌情考慮。
圖片優(yōu)化總結(jié)
- 不留不必要的A通道儿奶,不留不必要的A通道框往,不留不必要的A通道
- 其實Unity已經(jīng)做得足夠智能了,一般你只需要選擇貼圖類型如texture,還是sprite,還是litmap闯捎,他就能自動處理好大多數(shù)了椰弊。
- 2D圖片,移除mipmap瓤鼻,質(zhì)量要求高的選用trueColor,要求低的選用16bit或compressed
- 3D貼圖秉版,酌情關(guān)閉mipmap,優(yōu)先選用compressed,謹(jǐn)慎使用trueColor茬祷。
- 合理選擇圖片大小清焕。
高級優(yōu)化
16bit的優(yōu)化
使用16bit時,會出現(xiàn)明顯的顏色過度不均勻,可以通過RGBA4444和dithering優(yōu)化顯示效果秸妥,詳細(xì)請看(翻墻才見圖片)
http://electronic-blue.herokuapp.com/blog/2013/05/reduce-memory-usage-by-dithering/?utm_source=tuicool&utm_medium=referral
利用StreamingAssets的優(yōu)化
一張1024x1024 RGB24的圖片內(nèi)存資源大小為3MB滚停,而一張1024 x 1024的JPG圖片如果優(yōu)化得當(dāng)僅幾百K,可以將JPG圖片放在StreamingAssets下粥惧,讓后運行時讀取键畴,這么做確實能夠在保證質(zhì)量的條件下節(jié)省很多大小,但加載十分慢影晓,需謹(jǐn)慎使用镰吵。
分離Alpha通道優(yōu)化
壓縮格式能夠做到高質(zhì)量小空間,但壓縮格式一般對Alpha的支持較差挂签,也就是說如果一張ARGB的圖可以去掉A通道疤祭,就可以使用壓縮格式來優(yōu)化大小。
可以通過將Alpha通道提取出來作為另外一張圖的R通道饵婆,那么我們將得到兩張沒有Alpha通道的圖勺馆,且代表Alpha通道的圖可以縮小尺寸,兩張沒有A通道的圖一般可以比一張帶A通道的圖小侨核,所以這個優(yōu)化從原理上可行草穆,也有很多游戲這么做,但是需要額外處理shader搓译,且渲染時需要解析兩張圖等悲柱,綜合考慮目前我們沒有采用這種方式。
聲音
聲音資源在Unity打包時以流資源存在(待驗證)些己,也就是說文件大小會影響打包大小豌鸡,Unity預(yù)覽窗口中顯示的大小是內(nèi)存占用。在Unity中調(diào)節(jié)聲音文件參數(shù)不會影響打包大小段标。
影響聲音文件大小的因素 待補(bǔ)充
模型
選擇模型導(dǎo)入中的mesh compression 可以減少模型占用包體大小涯冠,但會出現(xiàn)一些變形和UV精度丟失等,調(diào)節(jié)壓縮到可接受的等級即可逼庞,如果是UV精度丟失(常見任務(wù)對稱中心出現(xiàn)一條縫)可以將貼圖畫出UV線更多蛇更。
動作
選擇動畫導(dǎo)入中的Anim.Compression可以減少動畫占用包體大小,同樣可能出現(xiàn)動畫變形等赛糟,調(diào)節(jié)到合適參數(shù)即可派任,一般選擇keyFrame reducion。
場景
StaticBatch大小優(yōu)化
場景本身在包體大小上并沒有太多可以優(yōu)化璧南,但需要注意如果你的場景大量使用StaticBatch掌逛,你會發(fā)現(xiàn)勾選StaticBatch的場景打包后比不勾選StaticBatch要大,估計Unity在打包時把StaticBatch的網(wǎng)格合并成了一個穆咐,比如你有一棵樹,這棵樹本身只占一個模型大小,這棵樹在場景中復(fù)制很多份仍然只占一個模型大小对湃,但如果這些樹勾選staticbatch崖叫,那么打包時會合并為一個樹林,原來的樹模型就不需要了拍柒,而是變?yōu)榱艘粋€大樹林模型心傀,大小自然變大了
解決辦法:取消場景的StaticBatch,取消后DrawCall無法合并拆讯,通過調(diào)用StaticBatchingUtility.Combine
進(jìn)行批處理即可達(dá)到原來的效果脂男。這個做法可能會導(dǎo)致場景加載時間變長,但一般感覺不出來(待測試)种呐。
BuildReport插件
https://www.assetstore.unity3d.com/cn/#!/content/8162
Unity每次打包后會生成一個文件記錄哪些資源被打包了宰翅,BuildReport可以解析這個文件讓你非常方便的查看哪些資源占用空間多,針對性的處理爽室。