2017年度大賞 | 最受歡迎的十個UWA問答

原文鏈接:2017年度大賞 | 最受歡迎的十個UWA問答

新年伊始,隨著大家緊鑼密鼓地開始了工作,UWA每周推送的知識型欄目《厚積薄發 | 技術分享》已經伴隨大家走過了100個工作周。回顧兩年多來,我們分享了近500個和遊戲開發、優化相關的精彩問答。這些問答不僅有具象明確的提問,也有詳細周全的解答;既能供研發團隊自身項目中即學即用,還能通過參與者的回答分析,幫助我們在解決問題的過程中觸類旁通、鑒往知來。我們優選了10個開放性的精彩回答,分享給大家。

UWA QQ群:465082844

UWA 問答社區:answer.uwa4d.com


1、如何在項目初期確定美術規範?

在項目初期,沒有任何正式美術資源的情況下,如何給出一個美術資源製作的規範給到美術呢?我明白,就上面的策劃需求不能得出一個精確的製作規範,只是想要一個大概的推算方式,給出一些大概的參數,好讓美術有規範可以參考。不知是否能給些指引?

美術也可以按他們想要的精度先製作部分角色和場景,但只有有限種類的資源的情況下,有方法測算出這個精度在性能允許範圍嗎?也就是說這個精度滿足策劃需求,可以作為美術製作規範。例如只有一個角色(5000面,512貼圖三張,80根骨骼),策劃同屏要求20個,就在場景中擺20個一樣的角色進去(因為只有一個),如果目標手機不崩潰,以后角色的製作就按這樣做。這樣可以驗證這個精度嗎?

精彩回答1:

作為經歷了一個新項目在大家都沒經驗的情況下做出一個剛小範圍內測遊戲的苦逼開發者,結合群里討論,個人覺得以下經驗可以參考:

1)選好對標遊戲,扒資源來參考。比如暢銷榜上的遊戲,把資源解出來看,參考模型面數和貼圖等遊戲。這樣最壞的情況下,參考別人能跑上線收到錢的遊戲,收錢不保證,但是遊戲性能的坑會少很多;

2)所有口頭或文檔的規範,都是無效的,不可能得到嚴格遵守,也就是說,不能用程序檢測的規範都是空規範,全部做成Editor菜單檢查校驗;

3)用同一個英雄放20份測同屏的方法是不靠譜的;

4)從gfxbench.com上根據跑分選好基準機型,比如假設要兼容的機型是跑700幀的,那麼基準機型得選6000幀的,預留好性能空間,性能別用得太滿,否則沒迴旋餘地:

5)貼圖少用RGBA32,讓美術在做圖的時候,做出來一律以壓縮模式的紋理來走Unity導真機包來看效果,千萬別只是把美術圖導手機相冊里看效果,這會和真實的遊戲效果有所偏差。建議規範只留兩張2048*2048的紋理空間給美術發揮,其餘全壓縮,否則等美術在高畫質模式作出效果後不肯降效果,逼程序優化,性能損耗非常大,程序會萬分苦逼。

感謝李先生提供了以上回答。

精彩回答2:

這確實是個見仁見智並且取決於項目類型的問題,不過題主是在項目初期,想要快速迭代出策劃的設計原型,並且要快速製作並且不用與程序產生過多溝通,在此前提下我覺得設定美術規範的首要目的是:不失控。製作出性能優秀的原型不是前期的目的,但畢竟是項目進展的一部分,如果美術資源製作沒有標準規範參考,如果隨便一個場景都是幾十萬面,DrawCall超過300,Overdraw可視化都紅得發白,那到後面整個團隊都要為此付出時間和精力,甚至返工。所以基本的製作規範也是十分必要的。

其次,在項目前期如何看待優化這個問題呢?我覺得過早的優化也是沒有太大意義的,談優化必須首先定位瓶頸,否則盲目優化除了降低資源質量和運算精度,對項目很難起到正面作用。這時項目處於快速變化中,不適合過早斷定,所以在這個階段依然是保證項目即使沒有很優秀的性能,但是也沒有很嚴重的問題,這就已經及格了。到了項目後期優化與效果的博弈,這又是另一個話題了。

在以上前提下,假設題主製作的是一個RPG遊戲,主城+若干小副本推圖,中端手機 iPhone 5,沒有程序的太多干預,那麼我的建議是:

1)大致規定好項目在 Unity 中的資源組織格式;

2)設定好 3dmax 導出模型的比例標尺,最好與 Unity 大小 1:1;

3)場景總面數均值5-6w左右(大部分),最高10w(少部分),單個模型300-1500面,攝像機可見部分2w以下,導出去除廢點,多餘的法線(如果沒用的話),盡量單面;

4)場景總面數還要看同屏戰鬥人數多少做調整,Drawcall最好不超過50,一邊給角色和特效留下空間,總 Drawcall 不要超過250這個盡量保證;

5)場景物體每個模型一個材質球,貼圖256為主,正方形,pot(長寬2的倍數);

6)嚴格限制場景中透明片的大小和重疊的個數,盡量少用,減少面積;

7)角色面數部分,主角1500以下;特殊boss2000以下;精英怪物1000面以下;普通怪物800面以下;

8)每個角色一個材質,除了特殊部件(翅膀等)一律不使用透明材質;貼圖長寬相等,符合pot,128-256為主,最大不超過512;

9)去除 IK 節點和所有不必要的網格,對齊模型中心點與坐標原點;

10)預先規定好角色需要換裝的所有節點名稱,並且將需要換裝的部分規定好並製作時拆開;(建議將臉部單獨拆卡,臉部可增加面數);

11)角色骨骼30-35根為主,特殊大boss適當增加,超過40慎重考慮;

12)可以考慮動畫幀率10幀每秒,視具體情況或者不限制;

13)粒子單個發射器不超過50,每個特效最好10個粒子以下,同屏不超過500(200太低難以達到),盡量減少材質和粒子種類,大小,面積,層疊數等,粒子真的很費;

14)攝像機一定要調整遠近裁剪面,盡量降低遠近裁剪面的距離,默認數值過大,也千萬不要圖方便設置比如 0.1-2000這種,該數值極大影響低端機的深度緩存精度,引起過近的物體穿插閃爍;

15)使用最簡單的線性霧,同時善用霧效和攝像機的 culldistant 功能,裁剪掉霧效淹沒出的場景部件;

16)可向程序提出貼圖導入自動處理工具,比如角色貼圖:普通貼圖 _D 結尾,法線貼圖 _N 結尾,導入時工具自動設置大小和格式;

17)如果某個資源大於5MB,那麼要仔細查看是否真的必要;

18)如果成使用工具完成的資源檢查和設置,那麼都盡量提出需求讓程序滿足;

19)最好有個人專門負責檢查和整理資源;

以上只是摘取了一部分影響比較大的提了出來,也有一定的項目類型針對性,請根據自己的項目酌情參考和調整,實際細節還是比較多。另外,美術同學要善用 Unity 已經提供的各種工具,比如:面數, DrawCall,OverDraw 等等,這些都是直接又重要的基礎指標,需要隨時關注。美術同學也可以一開始不需要非常清楚這些標準背後的含義,盡量地去貫徹執行,久了就慢慢能理解,有空自己多去思考和追究;這些標準可以為少數情況酌情開特例,但不要太多。

感謝Yaukey提供了以上回答。

此問答來自於UWA 問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


2、美術資源導入管理

我們每次大批量地合入美術資源時,經常會出現構建出來的版本出現材質引用丟失、Animator Controller引用錯誤、貼圖引用錯誤等資源引用錯誤的問題,美術資源在本地是正確的,其他人機器上Editor看也是正確的,構建機Editor看也是正確的,但構建出來的Bundle是壞的。有時刪除Bundle再編會解決,有時則不行,目前遇到這種情況,只能讓程序同事在構建機上刪Meta重新做一次Prefab,費時費力而且不規範。

想問問這是Unity的Bug嗎?大家有沒有規避或者優化的方法?在管理美術資源合入的時候有沒有更好的流程,我們目前使用Perforce管理Unity工程,要求美術顯式上傳資源配套的Meta文件。

精彩回答:

我根據我們項目遇到過的問題猜測下,我覺得項目資源導入某個地方有問題的可能性更大些,題主是否可能存在以下情況:

1)是否使用代碼混淆。在Prefab 上掛的腳本忘記添加到排除混淆的列表,導致序列化的欄位被混淆,打完Bundle後的Prefab資源載入時候,掛接的腳本出現引用錯誤;

2)資源導入都重載過OnPostProcess並處理了資源設置,這一步是否修改了什麼不合理的地方,比如破壞了引用關係;

3)打包AssetBundle時,在構建Bundle 之前有沒有使用文件操作API(不是 Unity 的AssetDatabase的API)來直接修改了某個文件夾或者其他會破壞引用關係的行為,然後構建Bundle,完成後恢復文件夾名字(或者恢復資源原始狀態),這樣丟失引用關係的幾率很大;

4)有沒有可能發布機器上,看著正常,但是Perforce裡面已經存在一堆已修改的Meta文件;這種問題常出現於美術本地有兩個A1,A2個相同資源在不同文件夾,A1受版本控制,但是由於某種操作,本地臨時資源A2使用了原本A1的Guid,原本正確的 A1 被迫使用了不正確的新生成Guid(相當於兩人交換),然後上傳了A1的Meta,結果發布機器的下來的A1 Meta就會跟別人丟失引用,或者更新下來本地重新分配了新的Guid;美術策劃最容易犯這個錯誤;

5)我們是Unity 5.3.8p2,上周遇到一個疑似bug,美術多上傳了一組相同的資源,我們更新下來都會重新生成Guid,但是很多掛起的Meta在Unity里重新導入後,在版本控制里神奇地消失了,但修改還在;

6)如果都不是,只能嘗試最小排除法了,刪除項目絕大部分資源,一點點增加,然後打包,重現,排除原因;不行的話然後刪除代碼,一點點添加,打包,重現...有時候笨辦法也是最容易接近真相的。

該問題來自UWA問答社區,感謝Yaukey提供了回答,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


3、Camera開啟HDR對移動遊戲的影響?

我看到很多炫酷的效果都是用Unity的後處理來實現的,要求Camera開啟HDR。但是我不知道開了這個選項會不會很耗,在中低端機上能跑起來嗎?另外,使用HDR之後,Camera的Rendering Path是不是不能選Forward?

精彩回答1:

使用HDR可以選Forward,和Rendering Path的選擇並不會相互影響。 在手機上單純開啟HDR(fp16)性能的影響並不會很大,各種後處理Pass的開銷是要優化的重點。因為一般不會單純開啟HDR而不使用後處理,綜合考慮到發熱量等因素,不建議低端機器使用HDR和後處理,中高端再開啟HDR並配合後處理,並對後處理做基礎優化:比如適當降低後處理解析度,盡量合併多個後處理流程到一個Pass等。

感謝賀甲提供了回答

精彩回答2:

開啟HDR本身只是為後處理準備需要的數據,關鍵在於後處理的效率。假如說的是整個HDR實現的話,佔GPU總體時間是一個相當可觀的數值,大概可以認為是用帶貼圖透明片整屏繪製4,5遍左右的量(大概在這個數量級)。如果你只是想做泛光,使用更低質的效果的話,會好很多。

問題是,部分上古機型(諸如我的舊安卓機)本身對unity的後處理不兼容,只要對當前屏幕緩衝做任何操作都會導致卡死,不使用後處理主要是兼容方面的考慮,也就兼帶著無法使用HDR了。

但是目前完全可通過兼容性測試來決定特定機型後處理的開關,一刀切的方式並沒有必要。但這樣又有一個問題:特定後處理提升的畫面效果是否對得起它的消耗?是否有其他非後處理的方式可以實現類似的效果而消耗更低?(比如僅僅實現小物體的泛光用透明圓片堆疊效率比正常的Glow效率更高,雖然效果不好),這些也是導致後處理沒有廣泛使用的一個原因。

所以要看你具體想要實現的效果了。畢竟PSP這種機器末期在機能受限情況下也都在勉強實現後處理泛光效果,說明玩家其實還是有這樣的需求的(雖然你拿出這樣低質的效果很容易被產品BB糊了不如不加什麼的……)

感謝唐翎提供了回答

精彩回答3:

手機上基本都是forward並不影響。不知道5.5.x情況。從5.6.x開始是可以通過設置Tier settings 來調整hdr mode. 有FP16也有R11G11B10格式。這兩年手機GPU GFLOPS已經有了飛躍性的提升。附加個數據:比如meta9 一套4-5個後處理下來GPU消耗2-5ms.

感謝蒙占志提供了回答

此問答來自於UWA 問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


4、如何加快打包速度?

目前我們項目打出來的APK大小在120MB 左右,打一次包平均耗時在20~25分鐘。Build過程中絕大部分的耗時在「Building Scene0」和「Building additional assets」這兩個階段。請問這兩個階段Unity具體是在做哪些操作?有沒有什麼方式可以減少這階段的耗時?另外如果從硬體層面考慮,如何更有效地提高打包速度?提高硬碟的讀寫速度和CPU的性能又分別能帶來怎樣的耗時收益?

精彩回答1:

我們使用的是AssetBundle的方式,目前600MB的包,沒有太多資源修改的情況下,安卓包出包大約10分鐘左右,之前是7-8分鐘,不修改C#代碼單獨出Patch的話大致在5-7分鐘。

我們在用的安卓打包機價格大約是1萬左右,多CPU並且保證單核CPU的性能也是盡量高一些,SDD肯定必備,其他的沒什麼關係。

我們的CPU使用的是:Intel(R)Xeon(R)CPU E5-2683 v3 @ 2.00GHz 2.00 GHz

提醒一下關於貼圖壓縮,之前我們一直被貼圖壓縮折磨,高品質實在是太慢,後來我們是區分了Dev和Pub版本,Dev版本本地貼圖壓縮使用Fast,發布用的Pub版本才用Best的品質,速度快了非常多~即使美術大量修改貼圖,Dev版本出包也很快。

感謝賈偉昊提供了上述回答。

精彩回答2:

我很久之前在Github上發現了這個東西:

pvrtextool_wrapper:https://github.com/fxgames/pvrtextool_wrapper

Unity打包會調用pvrtextool,通過這個wrapper替換掉原始程序,這樣可以在打開發版本時,強制把壓縮質量設置到fast模式,這樣就可以節約大量的時間,而不需要修改任何貼圖的壓縮質量參數。如果覺得Mac Pro太貴了,可以試一下這個方法。

感謝lujian提供了上述回答。

精彩回答3:

Building Scene 是Unity在打包場景資源中,Building additional assets 是Unity在打包Resources中的資源,我們項目接近600MB了,每次出包都要50分鐘以上,苦不堪言。你可以嘗試這樣:

1)把資源全部使用AssetBundle的形式。除了第一次,在下次出包的時候,只會打包有變化和增量的資源。因為Resources的每次出版本都會重新打資源。這樣可以將沒修改的資源打包耗時省下來。

2)配置個好的電腦,把CPU換個好點的,硬碟換成SSD的。

以上2點能節省你出包的時間,目前也是我們使用的方法

感謝 hejianchun提供了上述回答。

該問題來自UWA問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


5、如何在PC上檢查美術的特效性能?

有沒有比較好的辦法在PC上檢查美術的特效的性能?我們之前做了個粗略的方法,就是扔N多特效在場景里,檢查一下幀數,但是效果感覺不是很好,想聽聽大家的意見。

精彩回答1:

我們是寫估分公式,也就是按一定的規則,遍歷整個特效,根據節點的屬性計算一個性能分。可以批量掃資源輸出Excel查看。復用一下代碼可以直接植入到編輯器,讓美術做的時候就看到這個分。 不用很精準,這種方法90%的問題都可以很快發現。還可以預先定好規範,結合特效的使用情景來估算特效同時出現數*特效性能分會不會超標。

感謝招文勇提供了回答。

精彩回答2:

特效吃性能主要是OverDraw導致的。我們沒在PC上檢查,是拿真機檢查。

PC的檢查是用了錢康來提供一個看OverDraw的腳本,美術可以在做特效的時候大概看一下OverDraw,根據情況來調整。

然後我們構建真機包的時候生成特效列表名單,然後在進到主城之後,在聊天節目輸入GM命令,遍歷播放特效,每個特效可以通過播放1到n份,然後通過AdvancedFPSCounter插件記錄當時的FPS值,記錄到文件里。

然後找出幀率低的時候是哪些特效,然後針對性優化即可。

比如代碼

if (cmd.ToLower().StartsWith("-gm texiaoplay3")) { Toast.ShowTip("測試美術做的一系列特效 " + cmd); prEffectTest(3); return true; }

private static void prEffectTest(int efCount) { if (BilinCamera.Instance == null || BilinCamera.Instance.player == null) { Debug.LogError("找不到場上英雄,因此不能測試特效"); return; } TextAsset conf = Resources.Load<TextAsset>("effeclist"); string[] lines = conf.text.Split(
); //先同步載入一遍 for (int i = 0; i < lines.Length; ++i) { string prefabName = lines[i]; if (string.IsNullOrEmpty(prefabName)) { continue; } } BLDebug.isLog2FileEnable = true;//開啟寫文件 GameManager.Instance.StartCoroutine(prEffectTestAsync(lines, efCount)); GameManager.Instance.StartCoroutine(logUsedFPS(efCount)); } private static IEnumerator logUsedFPS(int efCount) { float startTime = Time.realtimeSinceStartup; float crtTime = Time.realtimeSinceStartup; while (crtEffectName.Length > 0 && (crtTime - startTime) < 6000.0f) {//100分鐘內 crtTime = Time.realtimeSinceStartup; CodeStage.AdvancedFPSCounter.AFPSCounter aFPSCounter = CodeStage.AdvancedFPSCounter.AFPSCounter.AddToScene(); BLDebug.Log2File(TimeUtil.currentSqlTimestamp4LongAdv() + " logUsedFPS" + efCount + " " + crtEffectName + " " + aFPSCounter.fpsCounter.LastValue + " " + aFPSCounter.fpsCounter.LastAverageValue + " " + Time.frameCount + " " + Time.realtimeSinceStartup); yield return new WaitForSeconds(0.1f);//每0.1s採樣一次fps } yield return null; } private static string crtEffectName = "notbegin"; private static IEnumerator prEffectTestAsync(string[] lines, int efCount) { float periodTime = 5.0f; //開始逐個播放特效 for (int i = 0; i < lines.Length; ++i) { string prefabName = lines[i]; if (string.IsNullOrEmpty(prefabName)) { continue; } crtEffectName = prefabName; GameObject[] effectGoArr = new GameObject[efCount]; for (int k = 0; k < effectGoArr.Length; k++) { GameObject effectGo = PrefabUtil.loadPrefabToGameObject(prefabName, parentGo); effectGoArr[k] = effectGo; if (effectGo != null) {//是ui特效, GameObject.Destroy(effectGo, periodTime); } else { Debug.LogError("載入失敗???" + prefabName); } } yield return new WaitForSeconds(periodTime); } crtEffectName = ""; BLDebug.UploadTodayLogFile();//把當天的日誌傳到伺服器 yield return null; }

把日誌導入Excel進行分析即可。

感謝李宗波提供了回答。

精彩回答3:

我們分了兩塊:

1、特效釋放對於整體性能的影響部分,這個是針對結論性的統計,在真機上統計釋放之後的幀率波動,目前的版本只做了往場景里扔來記錄幀率的功能,主要評定特效對於遊戲最終的影響;

2、特效的Draw Call、面數和Overdraw影響。這塊的統計數據的獲取我們目前只能在PC上獲取,所以有一個工具在單機版本里逐個播放技能特效,統計對於上述三個指標的評價,找出超標的部分每周周會上給出報告列舉出來。

個人感覺資源的檢查一定有工具定期來做,持續監控才是最有效的優化方式。

感謝賈偉昊提供了回答。

該問題來自UWA問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


6、Graphics API的選擇

大家現在在工程里還是選擇只使用 OpenGL ES 2.0嗎?我記得以前大家都是這麼做的,現在這個做法過時了嗎?iOS 是否該加上 Metal?

精彩回答1:

我們目前都是用的Auto,主要有兩個原因:

  • Metal測試下來CPU Overhead會比GLES低很多
  • GLES3能夠有tex2Dlod支持 兼容性上來說只有實在老的機器和模擬器會fallback到GLES2,可能效果上會略差一些不過我們測試下來都可以接受。

感謝錢康來提供了以上回答

精彩回答2:

我們現在快要上線的項目選的是ES3.0,iOS和Android都是選的這個,iOS選Metal的時候遇到模型顯示不正常的問題,但是能力有限加上沒時間沒定位到原因,就統一成ES3.0了。選ES3.0還有一個原因,就是發現AssetBundle打出來的資源會比選Auto小很多。 還有就是目前我們的遊戲偏重度,不指望用老手機的玩家會付費,所以放棄顯卡太老的機型了。

感謝李先生提供了以上回答

此問答來自於UWA 問答社區:如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


7、多維度材質對效率的影響

在目前的Unity版本中,使用多維材質是否會對效率產生影響,用多維材質和把模型分塊哪個更好?

製作美術資源時,應該盡量避免使用多維材質。先舉例說明多維材質的一個優點是拆分模型做不到的: 一塊大石頭有石頭和草地兩個材質,做成一個整體的模型,使用多維材質,作為一個物件進行烘焙,在Lightmap上的UV分布是一個整體,不會出現拆分為兩個模型烘焙產生的接縫問題。

除了上面這種情況,其他情況下推薦將模型拆分成多個模型賦予不同的材質。優點是:

1、多個模型會作為多個MeshObject參與到裁剪、靜態批次等優化中;

2、拆分的模型和貼圖可以進行材質合併,程序才能進行下一步的優化,如果本身是多維材質,就無法進行合併DrawCall的優化;

第一個優點就能帶來很大的收益。製作上應該按照一個模型對應一個貼圖的做法進行,如果模型是一個整體,比如房子由底座、牆體、屋頂組成,建議將他們多選導出成一個FBX。

另外,不同材質的模型建議做成多個模型,再多選導出成一個FBX,仍然是一個模型對應一個貼圖的規範進行製作。

該問題來自UWA問答社區,感謝文雅提供了回答,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


8、AssetBundle粒度規劃

關於AssetBundle(下稱「AB」)拆分粒度問題。在我的項目中,我是基於邏輯以及最終的打包大小來分的,比如盡量不讓壓縮後的AB包超過1MB, 這是UWA之前的推薦,同時也是因為當前版本Android包的SerializedFile佔用大小(blog.uwa4d.com/archives)所考慮。經過這樣的規劃之後,我打包這塊的代碼基本是寫死的, 包括手動把公共包拆成多個(公共包略大,不拆的話壓縮後會有6、7MB), 還有每個AB包的內容也是人為拆成多個。 這樣雖然最後功能實現了,但個人依舊覺得不夠自動化。每次新添加資源的時候, 都得走一遍這種手動流程。也研究了別人寫的開源方案(github.com/tangzx/ABSys),全自動分析依賴關係,但問題是最後包打得實在太細了,不太符合科學(但還是推薦大家學習)。所以就想問下各位的公司項目是如何解決這個AB 粒度劃分問題的?

精彩回答1:

這是一個相當開放的問題,仁者見仁,智者見智。UWA目前無法總結出一個統一的方式來建議如何進行打包,首先需要說明我們看到的兩點情況:

1)沒有最好的打包方式,只有最適合項目需求的打包方式;

2)無論是粗粒度打包還是細粒度打包,現在都有成功的項目在採用,這說明只要符合需求,兩種打包方式都是很好的。

接下來,我們就粒度問題給出一些我們的看法:

1)AB粒度建議不宜過細,特別是一個資源一個AB

粒度過細,一方面會導致載入IO次數過多,從而增大了硬體設備耗能和發熱的壓力;另一方面,在我們測試過的Unity 5.3 ~ 5.5 版本中,Android平台上在不Unload的情況下,每個AB的載入,其每個文件的SerializedFile內存佔用均為512KB(遠高於其他平台),所以當內存中貯存了大量AB時,其SerializedFile的內存佔用將會非常巨大。同時,需要進一步說明的是,該問題已在Unity5.6中進行完善。

2) 在Unity 5.3版本之後,對於AB文件的文件大小其實不必再限定於1MB之內

之前UWA有這一限定是出於兩方面的考慮:一是New WWW在Unity 5.3之前是使用最為頻繁的AB載入方式(雖然現在也是),在5.3版本之前,New WWW載入會形成一個比較大的WebStream,一般來說是壓縮AB的4~5倍,會佔用比較高的內存;另一方面,當AB較大(比如大於5MB)時,其載入開銷會很大,由於是子線程中運行,所以真正反映到Profiler中時,大家會看到的一個「詭異」的CPU高開銷——Graphics.PresentAndSync,具體原因可以看這裡( 扒一扒Profiler中這幾個「占坑鬼」 )。所以,我們對此做了一些實驗,發現將AB壓在1MB以下是一個載入比較可以接受的情況。以上是我們之前為什麼會提出1MB的主要原因。但Unity5.3之後,隨著LZ4的引入,很多情況已經變化了,基於其Chunk的載入特點,AB載入很快,且內存佔用要比之前小很多。所以LZ4的AB其實可以考慮更加粗粒度一些。

但是,這裡仍然有以下三點注意:

1)對於需要熱更新的AB,也如問答中其他朋友的所言,要考慮實際情況控制AB的大小

2)即便是LZ4的AB,其載入方式不同,載入效率也可能完全不一致。以下是我們在UWA DAY 2017的分享,我們在兩個不同的AB(LZ4格式)中都載入同一個資源,唯一不同的是一個AB包含10個Asset,而另一個AB包含30個資源,以下是三種不同方式從載入AB到AB.Load的耗時對比。可以看出,New WWW載入出現了明顯的時間差異。因此,在Unity5.3之後,儘可能建議通過LoadFromFile(Async)來對AB進行載入。

3)對於AB的打包,儘可能把邏輯上同時出現(一個Prefab中非Share的Asset)、小而細碎的資源(Shader、Material、粒子系統等)儘可能打包在一起,並通過LoadAll來進行載入,因為這樣會帶來更好的載入效率。下圖為LoadAll和Load One By One的性能對比。在我們做過的實驗中,LoadAll確實會帶來更好的性能開銷。

上述是我們建議研發團隊在AB打包時的一些注意點,希望對大家的項目優化有所幫助。

此問答來自於UWA 問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


9、優化數據表的載入

安卓客戶端存在大量的模板數據需要配置,其中一些模板表甚至可能達到萬級的數據條目,那麼怎麼對這些數據模板表進行打包和載入,可以兼顧載入速度和熱更新表結構?目前的方案是採用Protobuf代替ScriptableObject進行序列化,可以實現熱更新模板表結構,但是載入速度相對ScriptableObject有較大的差距,目前數據模板載入較慢便導致了玩家進入世界的時間比較久。因此想了解大家有什麼好的建議呢?

精彩回答1:

本地讀取數據表是個老話題了。我不能完全解答這個問題,只能提供一下我過去項目的淺顯的經驗。用ScriptableObject或者BinaryFormatter二進位存儲然後反序列化成保存數據結構的對象,這兩種方法應該是載入速度最快的。

我們實際沒有採取這個方案,也使用的是Protobuf,是出於以下考慮:

- 一份二進位數據,客戶端和伺服器可以通用。從伺服器推數據很方便;

- 策劃習慣使用Excel編輯,有腳本可以把表格內容導出成Protobuf的二進位數據,另外,還有.cs/.go表結構描述文件需要重點考慮。也就是說,策劃修改表結構、增減表,伺服器和客戶端的結構描述文件可以自動生成好;

實際用下來,確實會有一些差距。如何選擇還是要看錶格的體量了。

感謝WangLiang 提供了以上回答。

精彩回答2:

我先把問題拆分一下,題主遇到的問題如下:

第一個問題:配置表存儲格式

現在主流的數據存儲基本分為三大類,各有優劣,需要根據實際情況選擇:

1、ProtoBuf或類似序列化庫,這種方式兼容性高,但是載入速度一般;

2、自己實現二進位數據存儲,兼容性差,需要精心設計達到較高的數據表達能力;

3、採用Lua熱更新方案的遊戲,普遍直接把數據存儲為Lua表。

第二個問題:配置表數據與代碼兼容

一般不建議大量修改數據結構,比如增刪欄位,如果實在無法避免,需要代碼連同數據一起發布進行熱更,做好版本管理即可。

第三個問題:配置讀取速度優化

1)先從數據量上約減,減小數據冗餘重複,數據存儲設計優化,多次引用的欄位多引用等等;

2)採用多線程載入,避免使用Unity提供的API,在遊戲啟動時,並行載入配置表,充分利用多核優勢;

3)就我們自己項目而言,沒有使用Lua的更新方案,但是我們依然採用Lua作為了數據存儲,經過優化後載入速度也不錯,可以參考 LuaTableOptimizer。

感謝Lujian提供了以上回答。

如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


10、Unreal 4 Shadow Map Cache

我想問下Unreal 4的 Movable光源的Shadow Map Cache問題,它的具體更新策略是什麼樣的呢?如何處理動態物體與靜態物體的關係?需不需要對Shadow Map進行Cascade?

我同時也參考了Cry Engine的文檔:

docs.cryengine.com/disp

同時如果想移植到Unity,可行嗎?或者我想解決大面積實時陰影的問題(光源方向會變化,大部分物體是動態物體 但是頻率都不高)有什麼解決方案嗎?我可以在光源Space下預烘焙數據來達到光源方向變化,用一張Shadow Map的可能性嗎?類似 Directional Light Map那種建立空間的?

精彩回答1:

Unreal 4的這個Movable Light的Shadow Map Cache只能給Static、Stationary物體用,因此我覺得其實是想給Movable光照下的Static物體陰影計算做個優化。但是Mobile端沒必要用Movable,Stationary就好,Static物體的陰影是預計算的。

Unreal 4的動態物體在計算陰影的時候會計算兩次,一次是從靜態場景投射到動態物體,一次是動態物體投射到靜態場景。在計算靜態場景投射到動態物體陰影時,引擎會緩存一張靜態場景的Shadow Map,用於計算投射到動態物體上的陰影。因此,對於動態物體也能接收到來自靜態場景的精確陰影遮擋,但是這個方式比較耗時,而且mobile也不支持。

Unreal 4也提供了類似Unity的對靜態場景投射到動態物體陰影近似解決方案,也是將shadow的預計算結果存儲到帶有間接光信息(也是SH)的點雲(在Unity中就是light probe)中,然後根據動態物體的位置從點雲插值出陰影遮擋,但是這種方式只能得到物體整體明暗度的變化,無法計算精確陰影。Unreal 4是推薦mobile上使用後面一種方法的。

需要補充一下的是,Unity解決動態物體接受靜態物體烘焙陰影也是採用Light Probe的。題主說是動態光源,動態物體,最好還是實時陰影計算。如果是採用Shadow Map Cache的方案做優化,可能得看具體場景和需求。預計算烘焙多個Shadow Map的方案可能需要考慮兩個因素,一是光源變化,二是動態物體變化。如果動態物體和光源變化頻率都不高,那麼可以嘗試對它們採樣預計算好Shadow Map。但是這樣帶來的Shadow Map佔用空間和內存開銷我們也不清楚,可能得嘗試一下才知道。

以上回答由UWA提供。

精彩回答2:

關於Unreal 4的實現,樓上已經說得很詳細了,可以參考Unreal 4源碼ShadowSetup.cpp/ShadowDepthRendering.cpp,搜索SDCM_StaticPrimitivesOnly相關的代碼即可,我補充一下其他問題:

1)針對動靜物體怎麼處理 在手機上比較難完美,可以針對靜物渲染一張SM,動態物件用planar shadow解決

2)Shadow Map Cascade 緩存的話,Shadow Map不能隨時更新,如果鏡頭頻繁大距離移動,cascade不能跟隨鏡頭隨時更新,過度可能會不自然,這需要根據項目特性權衡

3)能不能光源動,Shadow Map用同一張 看你怎麼動,如果是模擬日光,輕微轉角,那你只能放棄精確陰影計算,在判斷某個空間點是否在陰影區時增加偏轉角,相當於把陰影做平行四邊形變形 如果想360度轉,目前我也沒有很好的思路能兼顧cache和平滑轉動時的過度,畢竟物體的四面都長得不一樣,不可能用一張shadow map做平行四邊形變形而不穿幫。

感謝招文勇提供了回答。

該問題來自UWA問答社區,如您對該問題仍有疑問,可以轉至社區進行進一步交流。

answer.uwa4d.com/questi


推薦閱讀:

為什麼 Microsoft Word 不自動更新文檔目錄?
oppo手機跟vibo手機性能有什麼區別?
前端 白屏時間如何獲取?
動態追蹤技術:trace your kernel Functions!
預算4500左右配一台主機(僅主機)玩OW和GTA,求大神推薦一下目前這個價位才能配到最性價比的機器?

TAG:Unity遊戲引擎 | 熱門問答 | 性能 |