maybe I need grow more

 成長,也許從來都不是一件容易的事兒。

內存優化

圖形學、渲染優化

AssetBundle資源加載和卸載       Done

socket編程 (三次握手、四次揮手)

狀態機

C#高級特性 (閉包和匿名函數的區別)

lua編程            emergency

閉包和匿名函數的區別:

解釋1: 閉包是指有權訪問另一個函數作用域中的變量的函數。

解釋2:閉包是一個函數和該函數被定義時的詞法環境的組合,一個函數的返回值是一個函數引用,外部調用這個函數的引用時,需要堆棧中保留函數執行的變量環境,這種關係就叫做閉包。

匿名函數,一般用到匿名函數的時候都是立即執行的。通常叫做自執行匿名函數或者自調用匿名函數。常用來構建沙箱模式,作用是開闢封閉的變量作用域環境,

閉包跟函數是否匿名沒有直接關係,匿名函數和具名函數都可以創建閉包。

 

Unity5.XAB機制

http://www.cnblogs.com/murongxiaopifu/p/5629415.html#autoid-3-3-0

 

ChunkBasedCompression 新增LZ4進行壓縮,加載時不需要加載整個AB,只加載對應數據塊兒。

 

新增Manifest清單文件記錄AB依賴關係,不必要再需要人爲的處理PopAssetDependencies/PushAssetDependencis

 

AB壓縮格式:

Lzma 默認的ab壓縮格式,壓縮比很高,但是加載時需要整個加載ab文件,會影響運行時加載速度,形成較大的內存開銷。

不壓縮,不壓縮的AB加載速度快,但是體積大。

Lz4時5.3版本之後新增的壓縮選項,壓縮比沒有lzma高,但優點在於加載時不需要整個加載AB,因此在加載速度和內存上有較大優勢。

 

隨包的AB建議lz4壓縮,兼顧文件大小和加載速度,網絡更新的ab建議lzma壓縮,高壓縮比可以減少數據流量。

 

www(url)的加載方式,加載完成後會在內存中創建較大的webStream,通常爲原AB大小的3-5倍,便於後續加載直接從內存加載。

www.loadFromCacheOrDownload()改方法的優勢在於能將解壓縮之後的ab文件存入磁盤作爲緩存,只會在內存中創建較小的serilizedFile。而後的AssetBundle.loadAsset直接通過IO從磁盤緩存中獲取。

 

AssetBundle.loadFromFile 與老版本CreatFromFile機制上的區別在於,之前版本只支持從解壓後的AB文件創建資源,新版本對於無壓縮或者LZ4方式的AB文件可以直接創建AssetBundle對象。

 

UWA關於AssetBundle的建議:

1/ 對於需要常駐內存的Bundle文件來說,優先考慮減小內存佔用,因此對於存放非Prefab資源(特別是紋理)的Bundle文件,可以考慮使用WWW.LoadFromCacheOrDownload或AssetBundle.CreateFromFile加載,從而避免WebStream常駐內存;

2/ 而對於存放較多Prefab資源的Bundle,則考慮使用new WWW加載,因爲這類Bundle用WWW.LoadFromCacheOrDownload加載時產生的SerializedFile可能會比new WWW產生的WebStream更大。

3/ 對於加載完後即卸載的Bundle文件,則分兩種情況:優先考慮速度(加載場景時)和優先考慮流暢度(遊戲進行時)。

1)加載場景的情況下,需要注意的是避免WWW對象的逐個加載導致的CPU空閒,可以考慮使用加載速度較快的WWW.LoadFromCacheOrDownload或AssetBundle.CreateFromFile,但需要避免後續大量地進行Load資源的操作,引起IO開銷(可以嘗試直接LoadAll)。

2) 遊戲進行的情況下,則需要避免使用同步操作引起卡頓,因此可以考慮使用new WWW配合AssetBundle.LoadAsync來進行平滑的資源加載,但需要注意的是,對於Shader、較大的Texture等資源,其初始化操作通常很耗時,容易引起卡頓,因此建議將這類資源在加載場景時進行預加載。

只在Bundle需要加密的情況下,考慮使用CreateFromMemory,因爲該接口加載速度較慢。

儘量避免在遊戲進行中調用Resources.UnloadUnusedAssets(),因爲該接口開銷較大,容易引起卡頓,可嘗試使用Resources.Unload(obj)來逐個進行卸載,以保證遊戲的流暢度。

 

AB加載卸載的操作流:

 

各種加載方式的內存、性能對比圖:

內存優化&流暢度(fps)優化

代碼GC和卡頓:

字符串拼接、

循環內部New對象、

反射減損、FieldInfo/MethodInfo緩存

循環for/foreach/iterator、foreach效率最差

裝箱拆箱,

緩存所需的動態MonoBehaviour組件,或者在頻繁instantiate/destroy應考慮pooling

異步waitfor進行緩存

不再運行時大量使用閉包(閉包效率?)

儘可能重用容器,以及容器操作的合理性(dic/list擴容,移除順序)

不要大量使用delegate的-=/+=,

當你的對象訂閱了外部的事件,而又沒有取消訂閱,那麼該對象是不會被GC回收的!這會造成很恐怖的問題,產生了幾千萬個對象沒法被回收。而且匿名函數無法取消訂閱,就算是兩個代碼格式完全一樣的匿名函數,編譯器生成的也是兩個不同的方法簽名。鏈接:http://www.cnblogs.com/buptzym/archive/2013/03/15/2962300.html

減少不必要的 shader varients 

內存:

如果有較大的assetBundle,不要使用lzma格式,使用lz4

確保AssetBundle裏沒有重複的資源(AB依賴處理)

確保資源正確加載和卸載

不需要RW的texture&mesh關閉RW

不需要的texture關閉mipmap

模型頂點的normals和tangents,應該在導入設置或playersetting裏去除

確保大多數紋理使用壓縮格式(後處理工具相關)

確保貼圖尺寸合理、確保mesh面數合理

AnimationClip的分情況加載

fps:

減少meshColider的使用

適當情況下使用static batching/dynamic batching/自定義 batching

UI圖集的使用,動靜態分離,避免材質穿插、

使用合理的光照方案

使用合理的後處理

合理的骨骼數

合理的半透明物體佔屏比例,避免過多OverDraw

避免使用Unity自帶的地形系統

 

以下是關於品質控制

畫面質量控制:

**基本品質控制

實時陰影品質、骨骼動畫質量、紋理質量、垂直同步

**角色品質控制

根據和玩家主角的距離改變角色的渲染,如:是否開啓描邊、角色陰影模式實時/投影片兒/關閉、根據距離控制動畫更新頻率

**其他

分辨率整體縮放、根據對象layer控制渲染距離、根據配置切換抗鋸齒類型、後處理開關:FXAA(快速抗鋸齒/bloom/調色/鏡頭精神)

角色渲染優化:

**角色渲染合併

****紋理合並(通過相機拍攝RT合併、通過獲取TextureRawData合併、通過GraphicsCopy合併)

        支持不同平臺下支持不同的紋理壓縮格式,shader實際上對不同類型圖的精度要求不同。

****Mesh合併

        Unity的Mesh合併方法的問題:控制力不足、submesh合併會複製頂點,頂點數據翻倍

       自定義mesh合併:獲取所有mesh頂點、法線等數據、重新拼接成一個mesh。

****重新綁定動畫:skinMeshrender設置正確的bones、mesh有正確的BindPose--骨骼對應頂點信息。

        bindpose計算量巨大,使用ComputeShader將計算量推給GPU。

        bindPose預先烘培mesh數據

        部分不適合做合併的角色組件不參與合併。

總歸是在內存和DrawCall中尋找平衡。

 

 場景畫面品質控制

****在較低配置上減少細節的渲染

****減少難以觀察到的細節渲染

****在不同的品質上真的做出性能差異

****在低端機上也能有更好的畫面

****在高端機上將性能集中到更有意義的地方

具體手段:植被分組,賦予不同優先級,場景特效根據重要性設置不同layer,決定特效細節的展示分級、氛圍特效控制,設置相機最遠渲染距離。

lua基礎 / lua + ugui / lua和c#交互

c#和lua交互是怎麼實現的?

從最早的lua純反射調用C# ---> 純C#實現的lua虛擬機 ---->luajit+c#靜態lua導出方案

猜想1:lua虛擬機有lua堆棧的完全控制權,lua調用C#需提供C#函數的橋接代碼,並將其註冊到lua虛擬機中,即壓入lua棧。

c#調lua,首先lua虛擬機從lua棧中獲取函數信息,然後在lua編譯器在Global Table查找luafunction,並運行返回結果,將結果壓入lua棧,宿主語言可以訪問lua棧中的內存數據,返回給c#。

所以最重要的是搞清楚lua虛擬機工作原理和lua堆棧訪問。

tips:如何在lua調用中體現c#語言中的高級特性,取決於lua框架(xlua、tolua)的實現?

xlua如何實現hotfixed?

在需要熱更的類或者方法上打上[hotfix]標籤,然後在lua調c#的橋接代碼中獲取熱更標識,如果出現標識則執行lua補丁代碼,否則執行c#原生代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章