Unity 打包總結和資源的優化和處理


1. Texture,都去掉alpha通道,作為背景展示的圖片,基本都沒有透明要求,有特殊要求的則放到atlas里面
a. Loading圖這類需要比較精細的,則把圖片設置為Automatic TrueColor,設置真彩色,保證不失真
b. 地圖、縮略圖、UI背景圖等等要求不精細的,則可以設置為自動壓縮格式(有壓縮情況,都需要圖片寬高尺寸是2的冪,可以在Advance里面設置toNearest)
 
注意:ios下會自動把圖片寬高拉伸為2的冪次方尺寸,這樣會導致圖片顯示失真,解決辦法是制作圖片的時候就保證是2的冪大小。如果圖片顯示的區域確實不能做出2的冪大小,可以用補黑邊的方式把圖片做出2的冪大小,設置圖片的時候,就需要調整圖片的UV
要點:android下,帶alpha通道的圖片,自動壓縮是以ETC2 8bit的方式壓縮的,不帶alpha通道,是壓縮成ETC 4bit的格式(ETC2 支持alpha通道),ios下是壓縮成PVRTC 4格式。手機硬件對各種格式圖片的加載效率不一樣,RGBA32是最慢的。所以需要對圖片進行處理,改壓縮方式,ETC和pvr是加載最快的。
 
2. animation clip
動作片段的優化,主要是減少動作的無用幀,就是兩個Keyframe之間的旋轉或者位移或者縮放的差別很小很小,則可以把Keyframe去掉,這樣一個幾百k的動作片段優化下來可能只有幾十k,還是相當可觀的
 1 static List<Keyframe> TrimScaleKeyframes(AnimationClipCurveData curve)
 2         {
 3             List<Keyframe> keyframes = __keyframes;
 4             float maxValue, minValue, averageValue;
 5             keyframes.Clear();
 6             List<KeyframeSample> samples = TakeSamples(curve, out maxValue, out minValue, out averageValue);
 7             int depth = curve.propertyName.Split('/').Length;
 8             var kcount = samples.Count;
 9             keyframes.Add(samples[0].keyframe);
10             bool lastIsRemoved = false;
11             Keyframe lastKeyframe = new Keyframe();
12             var epsilon = m_scaleError;
13             float error = 0;
14             for (int k = 1; k < kcount - 1; ++k)
15             {
16                 var kf = samples[k].keyframe;
17                 var diff = samples[k].pos.y - keyframes[keyframes.Count - 1].value;
18                 error += diff;
19                 if (Mathf.Abs(error) > epsilon)
20                 {
21                     if (lastIsRemoved)
22                     {
23                         keyframes.Add(lastKeyframe);
24                         lastIsRemoved = false;
25                     }
26                     keyframes.Add(kf);
27                     error = 0;
28                 }
29                 else
30                 {
31                     lastIsRemoved = true;
32                     lastKeyframe = kf;
33                 }
34             }
35             keyframes.Add(samples[kcount - 1].keyframe);
36             if (keyframes.Count == 2)
37             {
38                 if (Math.Abs(keyframes[0].value - keyframes[1].value) < Mathf.Abs(m_positionError))
39                 {
40                     keyframes[0] = KeyframeUtil.GetNew(keyframes[0].time, keyframes[0].value, TangentMode.Linear, TangentMode.Linear);
41                     keyframes[1] = KeyframeUtil.GetNew(keyframes[1].time, keyframes[1].value, TangentMode.Linear, TangentMode.Linear);
42                 }
43             }
44             return keyframes;
45         }

 

 
3. 檢查無效的腳本
很多時候美術制作資源的時候,為了即時看到效果,會把腳本給掛上去,但是制作完以后通常會忘了把腳本卸載。通常這些資源會打包成bundle資源,這個時候腳本就會缺失,加載bundle的時候會一直報警告消息,這樣會增加CPU的開銷,嚴重的話會引起卡頓。所以檢查無效的腳本是很有必要的。不過有哪些無效腳本,這個就需要統計了,是個體力活
 
4. 特效的檢查
游戲里面的特效非常多,幾百上千個。而特效里面引用相同材質的情況是很多的,如果不把這些材質的剔出來,會造成很多資源的冗余。一個最簡單的辦法就是把所有特效的材質貼圖都摳出來打包成一個bundle文件,加載特效的時候動態加載材質貼圖,還是會減少幾MB內存的。
還有一點,特效貼圖很多都使用了alpha通道,渲染的時候容易造成重繪情況(alpha test和alpha blend),會加大CPU和開銷。解決辦法是拆分貼圖的alpha,shader里面做alhpa的混合。這樣會時游戲更加流暢一點,就是實現起來稍微麻煩一些
 
5. 場景處理
紋理合並+靜態批處理,lightmap貼圖設置自動壓縮。一個是減少drawcall,一個是減少內存占用。靜態批處理的
 
6. atlas貼圖
和特效貼圖類似,也是拆分alpha通道,在shader里面做混合。不過有一個很大的好處就是,atlas都是需要顯示很精細的,做貼圖壓縮處理的時候基本都是使用true color,一個1024x1024的 RGBA32的圖片在內存中會占用4MB的大小。做了alpha通道拆分后,就可以把alpha圖片和RGB圖片做自動壓縮成ETC 4bit格式,占用的內存會大大減少。對於游戲同時會使用幾個atlas的情況下,這種處理方式一個atlas大概就能減少2到3MB的內存,幾個下來,20MB都有可能,還是很客觀的
 
7. GameUI 游戲窗體界面
窗體界面在打包的時候把掛載的腳本去掉,加載窗體的時候動態掛上去。還有一點,打包的時候處理資源的依賴關系是很麻煩的,所以一勞永逸的辦法是,把窗體引用的atlas和font都去掉,在加載窗體的時候再動態掛回來,有點像腳本的處理方式,只是代碼實現上稍微復雜點,還是很簡單的。這樣也不用擔心窗體打包成bundle后過大的問題。200個窗體,通過這樣打包bundle,總共5MB左右,atlas和font單獨打包成bundle。還有一點,有些項目是把atlas、font、UI打包成一個bundle資源,這樣也可以解決重復依賴的問題。但是這樣會增加內存開銷,畢竟所有atlas、font、UI都一次性加載完了。所以一個文件打成一個bundle,在加載的時候可以使內存過度比較平緩。
 
8. 角色模型和怪物模型處理依賴
角色模型通常都會有幾套動作,所以打包角色模型時都需要先把角色上的動作給去除掉,游戲中在動態掛上去。這樣處理需要動作文件命名規范,有可能會用到配置表。
怪物、npc、坐騎等模型和動作基本都是一一對應的,不存在冗余的情況,所以不用拆分動作,直接全依賴打包
 
9. 音效、texutre不需要考慮依賴情況,直接打包。不過,因為這類資源本身都是經過壓縮的,打包的時候可以嘗試選擇不壓縮打包的方式打成bundle,加載bundle的時候就是加載的沒有壓縮的資源,可以提高加載資源的速度
 
10. 場景打包,unity 5.0以后加入了LZ4的壓縮方式,對比LZMA的壓縮方式,在加載速度上提升是非常大的,我測試過加載場景,使用LZMA的bundle同步加載時間是0.8s,使用LZ4的bundle加載的時間只有0.005s,快趕上不壓縮的方式了。一個場景文件通過LZMA壓縮后的大小是10MB, LZ4的大小是15MB,不壓縮的大小就是25MB。所以個人推薦還是使用LZ4的方式打包場景,不過也不是所有的場景都需要用LZ4,畢竟還是大了有大概0.3倍的大小。所以可以把游戲的前面幾張場景使用LZ4打包,后面的用LZMA。這樣,玩家開始玩的時候還是能有不錯體驗的。最終怎么取舍還是看項目具體的需求吧
如果資源采用不壓縮的方式打包,然后再對總資源進行zip壓縮,包體最終是小了,不過提交到ios后台看到的包體大小卻是zip解壓后的大小。目測ios后台是會自動識別zip壓縮的。一個辦法是自己寫壓縮算法,個人覺得還是比較麻煩。在手機硬件提升越來越快的情況下,沒有必要為了低端機做不壓縮的處理。中高端機對於不壓縮的資源加載和LZ4的資源加載,幾乎無感,孰高孰低,仁者見仁吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM