2016年7月31日 星期日

千呼萬喚 - Unity 5.4正式發佈

作者:ALEX LIAN 原文

讓大家久等了,Unity 5.4正式版現已發佈可立即下載

正如我們在3月份發佈的公告,我們在Unity 5.4的測試版裡額外放了很多測試資源,為了發佈品質及穩定性都達到最高。沒有這些測試用戶的幫助我們不可能做到,謝謝你們的Bug回報!我們想表達我們的謝意並對你們的付出給些獎勵,下面會一一解釋。

最近幾個月除了忙著發佈Unity5.4之外,同時我們也一樣繼續改善Unity 5.3.x讓它繼續堅定的成為現在開發中的專案的一個穩定平台。

快速地瀏覽一下Unity5.4主要改善:

圖形相關和渲染校能提升:

  • 更佳的多緒渲染
  • GPU Instancing用來減少Draw Call - 支援Windows、OSX、Linux、PlayStation4以及Xbox One
  • 改善低階圖形功能:貼圖陣列,計算著色器(Compute Shader)等
美術相關:
  • 得益於新的觸發器模組 - 尺寸控制器,以及光照探頭代理(LPPV)的光照更佳,粒子可以更個性化。
  • 引擎內建支援動態模糊渲染(Motion vector rendering)
VR改善:內建支援更多VR平台且校能表現更好

IL2CPP正式支援Android平台(之前被標記為「體驗版」)

Unity編輯器現在支援Mac Retina高解析螢幕顯示(Windows 的HiDPI支持正在開發中),還加了可縮放Game View的函式(OSX & Windows)

現在支援在Unity編輯器內設定Cloud Build

校能報告(
Performance Reporting)現已完全整合在Unity編輯器中,打個勾不需要安裝任何套件

Analytics分析的主要功能更新,原始數據(raw data)匯出,熱圖(Heatmap),即時串流(Live Stream),並且在面板加入Ads廣告數據

IAP現在支援Amazon商店

移除了目標平台Web Player、PS3,並且不再支持iOS6(現在支持iOS 7.x及以上版本)


下面為大家介紹具體細節

圖形相關和渲染校能提升:


更佳的多緒渲染
Unity 5.4將對多
緒渲染的支援提升了一個等級。它能根據專案和發佈的平台改善專案的幀率。

我們從Unity 5.3就想把粒子、圖片、火焰、光、線條及拖尾等等的渲染運算從主緒移除,在這個基礎上我們導入了並行式命令產生法(parallel command list generation)。不再將這些圖形繪製命令送給用來物理運算及程式使用的主CPU核心,而是分配到其他幾個CPU核心,以便複雜的場景可以更快地執行。

透過GPU Instancing減少Draw Call

Draw Call越少就表示效能越好。透過支援GPU Instancing的硬體來渲染大量相同Shader的物體只需要很少的Draw Call。

目前支援GPU Instancing的平台包括Windows(DX 11/12,Shader Model 4.0及以上),OS X,Linux(OpenGL 4.1及以上),以及PlayStation 4和Xbox One。更多平台支援正在開發中。

上圖的場景包含3種石頭網格。每塊石頭使用同一個材質並調整了顏色。第一個場景使用了有支援Instance的著色器,第二個場景使用內建的標準著色器。執行環境是Unity 5.4 beta,Windows D3D11,CPU 是Intel Core i7-4980HQ@2.8GHz,GPU是nVidia GeForce GT 750M。

改善了底層的圖形功能:貼圖陣列,Computer Shader等


如果你是自己寫Shader的圖形程式設計師,你可以使用2D Texture Array來幫助優化大場景渲染。原理是讓GPU將大小格式相同的2D紋理當作一個物件來處理。


我們還改善了一系列底層的圖形功能。Computer Shader現在可以透過DispatchIndirect串聯在一起,也改善了Compute Buffer計數器,以及用於除錯Computer Shader的除錯信息。使用新的CopyTexture函式可以快速複製貼圖,由於新增了著色器參數所以也能支援Uniform Array。我們在Metal、OpenGL及D3D9平台上實現了Alpha-to-coverage,iOS上可以支援Metal多緒渲染。最後,圖像特效也可以透過新增的ImageEffectAllowedInSceneView屬性作用於場景裡的相機。

美術方面改進:粒子光照更佳,新增動態模糊以及強化Cinematic Image Effect


新的粒子控制


Unity 5.4的粒子包含了新的大小控制,可以獨立控制粒子的寬度和高度,並控制網格粒子的全3D形狀。



我們還推出了新的觸發器模組,用來修改碰撞器列表中的粒子屬性。簡單來說,可以在粒子碰到碰撞體時銷毀粒子,但同樣也可使用自訂的程式Callback函式,現在可以調整所有的粒子屬性。查看下方的效果瞭解它的作用。



透過使用光照探針代理「LPPV」,可以使大量粒子系統的發光效果更加真實。這是一種讓無法取得光照貼圖的動態物體能獲取烘焙光照資料的方式。

LPPV的工作原理是在指定範圍中產生可以指定解析度並帶有插值光探針的3D網格。這樣就可以探測空間光線亮度變化。LPPV不僅僅只對粒子有用,還可用於大量的動態對象。



Cinematic Image Effects以及動態向量(Motion Vector)支援

最後,我們沒忘記 Cinematic Image Effects(像是屏幕空間光線追蹤反射(SSRR),景深(Depth of Field),色調映射(Tonemapping)和顏色分級(Colour Grading)等等),這些特效均已開放在 Asset Store 中下載(也歡迎修改並放到我們的 repo)。 Adam demo中就很好的利用了Cinematic Image Effects效果。



在5.4中,我們也加入了動態向量(Motion vector)支援。
動態向量可以從像素層追蹤每一幀的運動行為,並實現非常棒的後處理效果如動態模糊和反鋸齒(Temporal Anti-Aliasing)。舉個例子,目前Cinematic Image Effects beta版中就利用動態向量實現了非常逼真的動態模糊效果:



支援更多VR平台且效能表現更好

Unity 5.4現已內建支援OpenVR (SteamVR/HTC Vive), Oculus Rift, Gear VR, 和 Playstation VR平台,並針對這些平台進行了渲染優化。只需一個API就可以發佈到多個VR平台,將需要針對平台進行的調整降至最少。

為了達到這個目標,我們重建了VR子系統並清除不同VR設備相同功能的重複程式。在效能方面,我們加入了優化過的單通道立體渲染(Single-Pass Stereo Rendering,之前叫Double Wide Rendering),所以現在兩眼視圖都是單通道渲染,大大提高FPS。

如果想學習如何開始VR開發,可以看看這些教學和相關的免費資源來快速上手。

最後,如同在Google IO上宣佈的,Unity將原生支援新的Daydream平台。如果等不及整合也可到Google開發者網站下載 Google Daydream VR Dev Kit for Unity



IL2CPP支持Android平台

先介紹一下,IL2CPP是Unity的腳本後台,用來將Unity專案中的腳本和組件的IL(中間語言)程式轉換為C++程式,然後利用不同平台原生編譯器進行編譯。最明顯的優點就是改善了Unity運行腳本(遊戲邏輯)的效能。自Unity 5.0開始引入IL2CPP,最初是為支持WebGL而實現的,現在IL2CPP已完全支持iOS、 PS4和PS Vita,同時也在Windows Store/UWP 和 Xbox One上測試。

現在,我們很高興的宣佈IL2CPP已完全支持Android平台了!


更快的WebGL打包時間與WebGL 2.0體驗版
在5.4裡我們花很多精神在縮減WebGL打包時間,通過暫存在IL2CPP訊息並提供可用於開發打包(Development Build)的內建執行組件,現在只需重新構建開發者定義的程式即可。第一次打包仍需花些時間,但後面將是附加打包,因此會更快(你也可以將打包交給Cloud Build,見下文)

Cloud Build現在完全支援WebGL,你可以放心用Cloud Build來開發網頁遊戲。我們很高興能看到開發者採用WebGL作為遊戲的目標平台,例如Unite Europe 2016所分享的 Nordeus將《Top Eleven》移植到WebGL平台的故事。他們對移植到WebGL平台提供了非常有用的建議並且…收益增長了30%。

我們也非常高興宣佈WebGL 2.0在Unity中開放體驗版。儘管WebGL 2.0標準還是草案並未正式應用到目前正式發佈的網頁瀏覽器規範中,你仍可以在Unity中啓用WebGL2.0,並使用Firefox或者 Chrome先行體驗。取消勾選「Auto Graphics API」屬性並在列表上加「WebGL2.0」即可。




Unity編輯器支援Retina模式和可縮放的Game View
如果你是用MAC支援Retina開發遊戲,現在的Unity編輯器效果會更好。對於Windows的HiDPI支援也正在進行中。



另外,如果螢幕解析度太高,也可以對Unity編輯器中的Game View設定縮放來調到比較適合的解析度。OSX及Windows均適用。


Cloud Build現在可以從Unity編輯器中直接設定

使用Cloud Build可以幫你擺脫跨平台編譯及構建的繁瑣流程,加快專案的迭代時間。Unity 5.4可以直接在編輯器中啓用Cloud Build設定。此外還可在編輯器的Services標籤下查看狀態,不需要打開控制頁面。非常方便!


有興趣可以看看這段教學影片

Performance Reporting效能報告已完全整合到Unity編輯器,一個按鈕即可啟用


Unity Performance Reporting用來自動蒐集從不同設備平台的錯誤訊息,以便及時發現並找到問題。在Unity 5.4中,Performance Reporting已完全整合到編輯器中,一次點擊即可啟用,只需幾秒:



錯誤Log會顯示在下方報表中:



這還只是開始。效能報告的目的是為了幫助你更好理解遊戲內部的運作。異常報告是我們發佈的第一個功能,後續還有更多英文。

Analytics分析重要功能更新:收益報告(Revenue reports),即時事件(Real time events),新的Heatmap,原始數據導出(Raw data export)

隨著Unity 5.4發佈,我們也推出了Unity Analytics分析最重要的功能更新。可以在新的分析面板中查看廣告收益和ARPDAU(每日活躍用戶平均收益),使用 Livestream功能(只支援Unity Plus及Unity Pro)追蹤即時遊戲事件,使用新的熱圖來反映遊戲選定的關鍵指標,使用原始數據導出(只支援Unity Pro)功能可以很方便的下載所有的自訂數據分析。


現在Unity IAP(In-App purchasing)支援Amazon商店

我們在Unity IAP中增加了Amazon Appstore的支援。使用Unity IAP服務只需要一個API即可支援多個不同的App商店。


再見了Unity WebPlayer,PS3以及iOS 6

此前已宣佈,由於瀏覽器廠商逐漸不支援,所以Unity 5.3會是最後一個支援Web Player發佈的版本。當然,你也可以繼續使用Unity 5.3.x來發佈Web Player遊戲。或是時候轉向WebGL了!

考慮到iPhone用戶更新iOS最新版本較為即時(《Games by the Numbers 2016 Q2》報告顯示99.2%的iOS遊戲安裝在iOS 7.x或以上版本),這讓我們確認有必要從Unity發佈的目標平台列表中移除iOS 6。

同時,我們也很不捨地宣佈不再支持PS3發佈,以便專注於幫助大家做出更棒的PS4遊戲。

感謝測試用戶參與並提交Bug報告!

感謝參與測試的所有開發者。謝謝大家的努力,花時間升級專案到測試版並回報問題。由於你們用Unity的方式千奇百怪,幫我們解決了最難搞定的復現Bug。

所以,每位回報有效Bug的開發者都將收到一封郵件通知,以及Unity 5.4 beta特製T恤一件。除此之外,我們還會從中抽取100位贈送價值100美元的Asset Store現金券。快去看看信箱!

Unity 5.5測試版即將來臨

Unity 5.5測試版即將發佈,敬請期待。在開始之前可以先看看如何加入Unity測試(英文),或者看看Unity Roadmap來瞭解Unity 5.5的新功能。


想要了解Unity 5.4的所有更新內容,請看更新日誌

2016年7月24日 星期日

等等!我改變主意了! 如何在狀態機轉換過程時中斷

作者:CATHERINE PROULX 原文

最近解決了一個開發者回報的棘手Bug,這個Bug牽扯到空狀態(empty states)、覆蓋層(override layers)和轉換中斷(transition interruptions)。當我
進一步深入研究這個Bug的時候,我發現動畫系統文件中關於轉換中斷的描述太抽象了。經過內部討論後,我們決定發文說明一下。

下面我們來深入研究一下狀態機的轉換和中斷的細節。

預設情況下動畫系統裡的轉換是不能被中斷的,一旦開始由一個狀態轉換為另一個狀態,這個過程沒有出口。就像一個乘坐飛越大西洋航班的乘客,只能舒適的靠在座位上直到抵達目的地。一般來說對開發者是好事。

但是如果要對轉換過程有更多控制,Mecanim系統有幾種不同配置方式來滿足需求。如果對當下目的地不滿意,可以跳到駕駛員的角度在中途改變飛行計畫。這代表可以更靈敏的控制動畫,但同時也可能讓配置變得太複雜。

透過下面幾個例子來說明一下。首先是一個包含4個狀態
簡單的狀態機,名字為A到D,並且都指定轉換狀態連上狀態機。


預設情況下,當觸發了A->B的轉換後,狀態機將會從A轉換為B,中間無法阻止它變為狀態B。但是如果打開A->B轉換的檢視屬性,並將Interruption Source(中斷來源)從“None”變為“Current State”後,從A到B的這個過程就可以被狀態A的某些觸發器(triggers)中斷了。


為什麼是“某些”觸發器呢?因為“Ordered Interruption(順序中斷)”預設是勾選的。這代表在狀態A的轉換過程中,只有比當下轉換優先順序更高的轉換能夠被執行。查看狀態A的檢視介面可以看到只有 A->C這個轉換的優先順序比A->B高。


因此如果觸發了A->B,馬上又觸發了A->D,那麼轉換過程不會被中斷。但如果是A->C,A->B的轉換會被馬上中斷並且狀態機轉換至狀態C。

在系統內部,動畫系統記錄了中斷發生時的動畫狀態,並且將播到一半的靜態姿勢(X)和新的目標動畫進行漸變融合。


為什麼是靜態姿勢,而不是從A到C進行流暢的融合?簡單來說是為了效能。當遊戲必須要快速判斷中斷條件或是同時追蹤幾個不同的動態轉換時,將使得動畫系統不好擴展,因為每增加一個新狀態都會消耗更多的系統資源。

現在,如果取消勾選“Ordered Interruption(順序中斷)”,那麼A->C和A->D都可以中斷A->B的轉換。但如果它們在同一幀觸發,那麼A->C仍然會優先執行,因為A->C的優先順序更高。

如果將Interruption Source改為“Next State”,A->C和A->D將不再中斷轉換,不論它們的順序如何。但是如果觸發了B->D,則會馬上開始A到D的轉換,並不會完成到B的轉換。

轉換順序對於狀態B來說也很重要。“Ordered Interruption”的勾選已經不能用了,任何從狀態B觸發的轉換都可以中斷A->B的轉換,因為它們都沒有相對於A->B的優先順序排序,但狀態B的轉換順序會決定在同一幀都被觸發的情況下最終將轉換到哪個狀態。在這個例子中,如果B->D 和 B->C在同一幀觸發了, 則B->D會被選中。


最後,想要完全控制,可以將中斷來源設為“Current State Then Next State(先當下狀態再下一狀態)”或者“Next State Then Current State(先下一狀態再當下狀態)”。在這種情況下,轉換會先在一個狀態下獨立分析,然後再到另一個狀態。

所以,如果使用如下配置:


在狀態A到B的轉換過程中,有個玩家在同一幀觸發了4次轉換:A->C,A->D,B->C,B->D。結果如何呢?

首先,勾選了“Ordered Interruption”,所以可以直接忽視A->D,因為它的優先順序不如A->B高。當下狀態會最先處理,所以不用看A->B了,這裡進行的是A->C的轉換。




但是,相同配置條件下,如果只觸發了B->C和B->D,那就會進行B->D的轉換(它比B->C的優先順序高)。

現在還只是一個轉換,所有其他的轉換也是可能以其特定的規則被中斷的。所以如果讓A->C的轉換從下一個狀態中斷,那可能A->B的轉換會被A->C中斷,而反過來A->C的轉換也可能會被C->D中斷。

有一點很重要,不管中斷在何處發生,原狀態會保持不變直至轉換結束,而Animator.GetCurrentAnimatorStateInfo()將始終返回起始狀態。

簡而言之,狀態轉換的中斷設置非常強大,也提供了極高的靈活性,但也會讓人非常迷惑。所以要明智的使用狀態轉換中斷,有問題一定要先在編輯器中測試。

2016年7月21日 星期四

2016年Q2手遊資料報告:金磚四國主導全球手遊安裝量

作者 LEON CHEN 原文

2016年Q2手遊資料報告中文版現已發佈!本季度報告顯示了全球手遊在不同平台、設備及地區的安裝量趨勢:


本季報告重點如下:

  • 金磚四國巴西、俄羅斯、印度和中國以總計全球遊戲下載總量的41%以及Android平臺的 42%下載安裝總量佔據了Top5裡4個席位。 在金磚四國中排行前五的Android移動設備廠商中有4家來自於中國。
  • Android以96%的遊戲下載安裝量統治了印尼市場,超過了Q1的榜首韓國和巴西(第1季度資料均為92%) 。
  • 2015年10月發佈的Android系統Marshmallow(6.0或以上)在Q2增幅很快,達到了7.5%的下載安裝量,是Q1的4.5倍,這似乎應歸功於各大主流設備製造商正慢慢將Marshmallow作為設備首選系統。 
  • 2016年Q2搭載iOS 9.0(2015年9月發佈)及以上版本的設備中,iOS遊戲安裝量超過第一季度的72%,達到了78%。 

這是與Unity Analytics團隊發佈的第三份手遊資料報告,資料來源於用Unity製作的遊戲提供的匿名資料。僅在2016年Q2就有23.8萬使用Unity製作的遊戲在17億的設備上貢獻了合計44億的安裝量。

取得完整的報告:

下載 - 英文版
連到Unity大中華區官方論壇 - 簡體中文版

更多關於Unity Analytics的資料

2016年7月18日 星期一

Unity專案資源載入與管理

作者:柳振東 Unity官方平台

之前分享了Unity專案設計與管理的一些注意事項,其中最重要的莫過於資源載入與管理。今天這篇文章將由Unity官方技術支持工程師柳振東,針對一些常見的Unity專案資源載入與管理問題進行解答。


 Q.將材質打包為AssetBundle,執行時使用LoadAsset載入材質也成功了,為什麼還會出現材質丟失的情況呢?


這也是開發者經常會遇到的問題。一般情況都是開發者先把被依賴AssetBundle的資源載入出來,然後用Unload卸載掉這個被依賴的AssetBundle,最後發現從其它AssetBundle中載入出來的GameObject丟失了前面載入出來的資源。

要弄明白這個問題,我們需要瞭解AssetBundle中的Asset在載入時尋找其依賴資源的規則。其實很簡單,現在AssetBundle實現的機制是只會在記憶體中尋找其依賴資源所在的AssetBundle,並自動從中載入出所需的資源。

那麼現在我們知道,其實通過LoadAsset從被依賴資源的AssetBundle中載入出來的資源,除非我們手動綁定回主體資源中(例如把載入出來的材質通過代碼綁定回GameObject的Renderer中),否則是不會被自動索引到的。

也就是說,通過AssetBundle來動態載入資源時,我們並不需要自己載入被依賴的資源,而是只要保證主體在載入時被依賴資源所在AssetBundle依然處於開啟狀態就可以正常載入資源了。


Q.為什麼遊戲切換到後臺一段時間後再切換回來材質會變成粉色呢?

大家都應該知道,粉色材質在Unity中是Shader出錯或丟失時的預設警告材質,而在這種情況下就是Shader丟失的問題。

首先我們要瞭解一個系統對於GPU資源管理的機制。在PC平台上,玩家在鎖屏一段時間後GPU會自動把部分幕後程式的資源清除掉,而Android或iOS這種手機系統一般會在切換到主介面或其它程式一段時間後進行類似的操作。

那麼當Unity程式在GPU中的Shader和Texture等資源被清除之後再切換回該程式時,CPU端會接收到GPU Graphics Context 丟失的消息,然後Unity會嘗試從記憶體中將丟失的資源重新載入到GPU端。

這時,如果原來的Shader和Texture資源是從AssetBundle中載入出來的,並且該AssetBundle已經被卸載掉的話,那麼Unity就無法再從記憶體中載入到這些資源,從而導致GPU丟失Shader與Texture了。

可能有朋友會說,這些Shader和Texture不是曾經被載入到記憶體中嗎?是的,但是它們在被載入到GPU之後會被從記憶體中清除掉。因此要防止這種問題的發生最穩健的辦法就是Shader和Texture的AssetBundle在場景切換前都不要卸載掉。
而如果擔心AssetBundle本身消耗記憶體問題的話可以參考下一個問題的解答。


Q.新的ChunkBasedCompression壓縮方式相比原來的壓縮方式有什麼區別呢,應該如何取捨呢?


Unity預設的AssetBundle壓縮方式是LZMA,這種壓縮方式的AssetBundle在載入到記憶體時會馬上執行解壓過程,並在AssetBundle處於開啟狀態期間在記憶體中保留一個解壓過後的Cache(例外情況:UnityWebRequest.GetAssetBundle與WWW.LoadFromCacheOrDownload均會在第一次解壓LZMA AssetBundle時把解壓後版本Cache到檔案系統中,後續的調用就無需在記憶體中保留解壓後的AssetBundle了),因此記憶體佔用會比較明顯。

而Unity5.3以後提供的ChunkBasedCompression是一種基於Chunk的LZ4壓縮方式,這種壓縮方式可以讓AssetBundle對單獨的Asset進行壓縮,而不是AssetBundle整體壓縮。因此載入這種壓縮方式的AssetBundle時,無需事先解壓,只需在記憶體中保留一個頭結構,然後在載入某個Asset的時候才即時從檔中讀取該Asset所在的chunk並解壓到記憶體中。

由於LZ4是公認的解壓速度極快的壓縮方式,並且需要即時解壓的資料量一般不會很大,因此即時解壓Asset帶來的CPU時間消耗其實很小,另一方面把解壓時間分散在不同地方也減輕了一次性解壓帶來的卡頓問題。當然,最重要的優點還是在於大大減輕了記憶體的壓力,可以放心地讓有可能被再次索引的AssetBundle常駐在記憶體中,因此我們非常推薦大家使用LZ4壓縮方式的AssetBundle。

不過大家在使用過LZ4壓縮方式後應該也會發現,在資源數比較多的情況下,LZ4格式的AssetBundle大小基本都要比LZMA格式的大一些,這也是分塊壓縮不可避免的缺陷。但考慮到它的記憶體消耗表現優秀,移動端的開發朋友應該可以忽略這一點吧。


Q.Resources資料夾裡的資源越多,程式的啟動畫面時間就越長。這是為什麼呢?


要理解這個問題,我們需要知道Unity程式啟動時的一個操作。在啟動載入的過程中,Unity需要為Resources資料夾(此時其實就是一個序列化檔)中的所有資源構建一個查找樹作為後面載入具體Asset時所需的索引資料,而這個結構的構造時間是非線性的(比線性稍高一點),因此在Resources資料夾中的檔越多,啟動載入的時間就越明顯,基本10000個資源在一些低端手機上需要5到10秒的載入時間。

另一方面,考慮到Resources資料夾無法動態更新,也沒有AssetBundle Variant這種設定不同資源版本的功能,因此我們極力推薦大家主要採用AssetBundle進行資源的動態載入,而Resources資料夾的使用可以只考慮這幾種情況:
  1. 這些資源在整個遊戲的運行期間都會用到
  2. 這些資源無需為不同平臺或硬體配合來自訂資源
  3. 這些資源無需動態更新
  4. 架構遊戲的雛形

Q.程式中主要使用AssetBundle.Unload(false)卸載AssetBundle,有時會發現AssetBundle中的資源在記憶體中會存在多份,這是為什麼呢?


這種問題產生的根源在於從AssetBundle中載入出來的資源,在該AssetBundle卸載之後與此AssetBundle的聯繫就斷開了。舉個例子,我從AssetBundle A 中載入出來一個Prefab p1, 那麼p1本身依賴的資源,例如一個Texture tex1也會自動載入到記憶體中。然後我用AssetBundle.Unload(false)來卸載AssetBundle A,此時p1與AssetBundle A已斷開關係。之後過了一段時間,我需要從AssetBundle A中載入另一個Prefab p2 ,假設p2也依賴於Texture tex1,那麼我再次載入AssetBundle A,從中載入p2時tex1會再次被載入到記憶體中,導致此時記憶體中存在兩份tex1。


這個AssetBundle的資源索引策略我們官方在之後的版本中會進行修改以避免這種情況產生的記憶體消耗。而現階段大家其實只要注意AssetBundle的卸載時機即可避免此情況的發生,意思就是在保證當下場景中同一AssetBundle不會再被引用的時候卸載或者統一都在場景切換的時候使用Unload(true)進行卸載。

關於AssetBundle的常見問題解答就分享到這裡,如果還有其它疑問,也可在訪問Unity官方中文社區(forum.china.unity3d.com)發帖提問。

2016年7月11日 星期一

物理系統最佳實踐 - Best Practices系列

作者:Ricardo Aguiar 原文

本文是Unity官方Best Practices系列文章之一,說明在遊戲中使用物理時的最佳實踐,並透過一些案例來說明為何要這麼做。

層(Layer)與碰撞矩陣(Collision Matrix)


所有的遊戲物件在建立時如果沒有設定層,預設會放在Default層,這代表可以和任何其他物件發生碰撞反應,這樣會導致效能不太好。我們應該為每一層設定好能夠發生碰撞的物件。因此我們得幫不同類型的物件設定不同的層。每新增加一個層級,碰撞矩陣裡就會自動加一行和一列,可以用來定義不同層之間的互動關係。

在預設情況下,新加的層在碰撞矩陣中被設定為可以與其它層發生碰撞,所以開發者需要手動設定層和層之間的互動關係。正確設定好層和碰撞矩陣,可以避免很多不必要的碰撞和碰撞檢查。為了展示我們建立了一個Demo,在一個盒子容器中實例化產生了2000個物件(1000個紅色,1000個綠色)。物體只會與相同顏色的物體以及牆壁產生互動。

其中一個測試是把所有物體的層都設為Default,然後從碰撞監聽(Collision listener)比對不同遊戲物件的標籤(Tag)來判斷是否進行互動。而在另一個測試每種顏色的物體都分為單獨的層,然後設定碰撞矩陣來定義層和層之間的互動關係。這樣就不需要用程式來比對了,碰撞只會發生在正確的層上。


圖1:碰撞矩陣配置

下面是Demo執行時的抓圖。用一個簡單的管理機制來統計所有的碰撞次數,並於5秒後自動暫停。結果相當的難以置信,使用第一種方法把所有物件都放在Default層會產生大量不必要的碰撞。

圖2:計時五秒所產生的碰撞次數(左:沒有設定矩陣,右:有設定矩陣)

我還用了Profiler擷取Physics區塊中的資料。

圖3:相同層和不同層的物理效能在Profiler裡的比較

正如在Profiler裡所觀察到資料情況,兩個測試對於物理計算上的CPU消耗截然不同。左邊使用相同層平均消耗約27.7毫秒,右邊不同層平均消耗約17.6毫秒。 



射線(Raycast)


射線是物理引擎中一個非常有用的工具。它可以向特定方向發射一條特定長度的射線,透過這個射線就能知道它是否擊中物體。然而,這樣的功能會產生很大的效能消耗。它的效能會受到射線的長度和碰撞體的類型很大的影響。

以下列出一些要點協助你更好的使用。
  • 使用最少的射線來完成任務。
  • 按需設定射線長度,不要太長。射線越長,需要檢查的碰撞物體就越多。
  • 不要在FixedUpdate()函數中使用射線,有時即使是在Update()函數中,射線也會導致過多的消耗。
  • 注意使用碰撞體的類型,射線與網格碰撞體(Mesh Collider)計算的效能消耗是相當大的。
    - 比較好的解決方法是使用多個幾何碰撞體來組合出物體的形狀。可以將父物件Rigidbody下所有的子碰撞體作為混合一起使用。
    - 如果非得使用網格碰撞體,至少將它設定為Convex打勾。
  • 為了確保射線會射到哪些物體,應在Raycast函式中設定層遮罩(Layer Mask)。
    - 官方文件有詳細的說明,要注意的是在Raycast函式指定的是bitmask而非不是layer ID。
    - 所以
    如果你希望射線到一個物件,它的位在layer ID = 10,在Raycast函式中應設定參數為1 << 10(將' 1 '左移10位)而非直接設定10。
    - 如果你希望射線擊中除了layer 10以外的所有物件,可以使用位元運算子(~)對bitmask反轉每一位元。

下面的例子顯示射線只與綠色盒子發生碰撞反應。

圖4:簡單的射線投射場景

透過射線的數量和長度來驗證之前提到的資料分析。可以從下圖中發現,射線的數量和長度對效能影響極大。

圖5:射線數量對效能的影響


圖6:射線長度對效能的影響

下面展示使用網格碰撞體代替幾何碰撞體的效果。

圖7:網格碰撞體場景(每個碰撞體有110個頂點) 


圖8:幾何碰撞體和網格碰撞體在Profiler中的情況

正如Profiler結果所示,射線與網格碰撞體的碰撞檢測在每一幀負擔都很重。


2D物理 VS 3D物理


Unity有2D和3D的物理引擎模式,為專案選擇最適合的物理引擎,如果只開發2D遊戲或2.5D遊戲(2D遊戲看起來有3D效果),用3D物理引擎就太浪費了。這樣會為專案帶來許多不必要的CPU消耗。作者推薦可以使用下面文章中提到的方法來檢查使用不同物理引擎所帶來的消耗:



剛體(Rigidbody)


剛體是為物件提供物理互動必需的元件。即使將碰撞體作為觸發器(Trigger)使用,也必需為物件加上剛體元件,好讓OnTrigger 事件能運作。沒有剛體元件的物件會被視為靜態碰撞體。這點非常重要,因為嘗試移動靜態碰撞體會帶來很大的效能消耗,它會迫使物理引擎重新計算整個物理世界的資料。還好當靜態碰撞體被移動時,Profiler會在CPU分析器上加一個警告標籤提示。為了展示移動靜態碰撞體所帶來的影響,我把之前第一個Demo中所有移動物件的Rigidbody元件移除了,然後透過Profiler分析器重新獲取資料。 


圖9:移動靜態碰撞體的警告(紅框)

如圖所示,總計產成了2000個警告,每次移動遊戲物件都會產生警告。CPU在物理計算上所耗費的平均時間約從17.6毫秒增加到35.85毫秒,這個消耗很驚人。因此確保當一個物件會被移動時,務必加上剛體元件。如果想直接控制物體的移動,只需簡單的勾選Rigidbody元件的的Is Kinematic屬性即可。


Fixed Timestep


調整Time Manager中的 Fixed Timestep值,會直接影響FixedUpdate()函數 和物理引擎之間的更新率。調的好可以在物理系統的精確度和CPU消耗之間達到一個平衡。 


總結


本文所討論的內容在設定上或製作上都不是很困難,而且會幫助你的專案帶來顯著的效能提升,因為幾乎所有專案都會用到物理引擎,即時只是碰撞檢測也會有所區別。


論壇作家 Ricardo Aguiar

Ricardo Aguiar是來自葡萄牙Azore群島的一個開發者,在遊戲行業擁有超過7年的專業經驗。他從完成碩士論文(使用跟蹤和視覺化設備開發遊戲)開始了遊戲開發之旅。隨後加入Seed Studios,致力於開發NDS,iOS然後在PS3上開發第一款葡萄牙語遊戲Under Siege。之後加入X-Team工作,並使用Unity引擎開發手游。

即時運算短片ADAM - 產品設計揭密

作者:GEORGI SIMEONOV  原文

*本文圖多且大,建議用1920x1080解析度閱讀

Unity即時動畫-Adam-完整影片


早先我們公佈了Unity引擎即時運算的電影短片 Adam 完整版。接下來的幾週我們會推出一系列文章,為大家分享Adam製作的各方面細節包含:概念、資源製作、引擎設定、動畫流程、視覺特效以及為專案建立的自訂工具等。我們還計畫後續會陸續發表專案的角色和環境,基本上所有的資源都可直接使用,不必依賴於還沒發佈的Sequencer工具。

除了發佈系列文章之外,我們也努力往正式發佈Adam專案。計畫將於今年秋季能公佈所有的資源和自訂工具。


關於我
我的名字叫Georgi Simeonov,負責Adam專案的藝術指導和產品設計工作。之前擔任過多款遊戲的概念美術,如邊緣戰士(Brink)、蝙蝠俠:阿卡漢始源(Batman: Arkham origins)和核彈風雲(Dirty Bomb)等等,還設計了The Blacksmith中的主角Volund。


世界觀
電影背景設定在一個人類社會已被殘酷的生物科技終結的
未來世界,人類文明也退化成零星且封閉的群體,死守著一絲關於過去的回憶。
Adam,我們的主角,是我們設計的出發點,他的人類意識被困在廉價的機器人中,這樣設計的目的是透過描述它作為人類囚犯的身份,來窺探整個世界複雜的背景故事。


關於Adam



褪皮的機械-身體
最初的想法是機械身體同時兼備和人體類似的功能性,身體構造和器官分佈都應該很像人類,在某種程度上就是模擬真實物體但精簡結構。從大方向定義到細部功能像是外表裝飾的細節,比如用鋼製的盒子做為頭蓋骨讓人聯想到人類大腦,並切割成類似大腦的褶皺,身體露出部分肋骨和脊椎,表現病人或屍體在手術或解剖中復活。


行走的犯罪紀錄-畫面
另一個主要的設計概念就是機器人用行走來抵銷他們的罪行,胸口的顯示器或平板會顯示它們的犯罪紀錄。大部分的機器人紀錄裡都有它們原來的臉部照片作為自己曾經是人類的參考證明,這樣會與機器人近乎空白的表情形成了強烈的對比。但在最後我們認為在胸口放人類臉孔會太過喧賓奪主,所以還是採用了簡單一點的設計。



Adam最初的草稿。因為是在假期時打的草稿,所以一開始是用一隻紅色鉛筆和原子筆在一個小本子上完成的。後來導演Veselin Efremov希望罪犯者看起來更加人性化,所以我們放棄了獨眼設計和怪怪的比例,用比較有利於人性化的設計




一些要素排列上的變化,這時設計上的很多關鍵要素已經定案



腿和手臂的力學機制。這裡我們不但做了對機械之間平衡關聯機制,也研究骨骼、肌肉、肌腱之間的互動。最後採用了類似自行車刹車線一樣的電纜機制,透過大部分隱藏在身體內的發動機來牽動每個部位




死亡面具 - 臉部

臉部被設計為死亡面具(Death Mask),我們簡單的對模型進行3D掃描完成了一個粗模。一開始是希望不論自然與否,在僵硬的表情上要有張嘴,但後來發現它會分散對於眼睛的注意力。所以最後就拿掉了嘴巴,也有助於讓焦點集中在需要注意的地方,同時也能強調罪犯的壓迫感。

臉部及面具參考


Adam面具設計演變過程


Adam早期概念造型


討論Adam和其它罪犯多種選擇的面孔時,我們很快發現非常容易會陷入一種情況,不認為這是人類角色,而是無臉人或外星人。



收縮膜-服裝

我們需要將角色一部分打扮為色,因為橙色會讓人聯想到囚犯的衣服。但機械軀體其實並不需要衣服,穿上衣服可能會有讓它們看起來像維護或工具機器人,所以我們採用收縮膜包裝來表示服裝,表現像是很多工廠工具把模拆開之後就能開始使用的感覺。


Adam皮膚和服裝參考

罪犯角色的收縮膜包裝

Adam-最終設計



最終的面具設計


最終的概念及模型

罪犯收縮膜包裝範圍



Sebastian, Lu以及警衛隊



兩個角色的最初草圖



Sebastian和Lieutenant最初的參考對象

我們認為另外兩個關鍵角色從一開始就要設計為一組互補的隊友。我們需要Sebastian看起來明智、威嚴但也很可怕,但並非好鬥。我們稱Lieutenant為Lu,是他的得力助手,平等且互補的角色,必要時採取任何侵略行動。

Sebastian

在設計這兩個陌生人的過程中,我們結合東方與西方救世主的概念,設計專屬於他們的能力,重點是必須讓他們出場短短幾分鐘裡傳達要表達的故事。

設計Sebastian的主要目標是表現出兩位旅行者作為外來已開發文化的呈現,並表達它們努力保留人性來掌握自己個性的能力。


我們希望Sebastian 形象復古,或許是第一代被轉化的,甚至是第一個被趕出去的。從那時他就帶有開啟新世代或重生新時代的想法。我們融合了多種元素,比如他前額的幼苗圖案和胸口上傳統象徵救世主的圖案。材質的角度來看,和我們最初的靈感非常接近,我們希望將Sebastian打造成了一個栩栩如生的青銅像。


臉部
Sebastian和Lu的面具或臉部有著那些需要重塑自己進而達到重生和表達個性的深度。我們研究出用雕刻或鑄造和彩繪或染色的外觀能強調出自我意識的面具。

Sebastian的臉/面具/頭套嘗試 




Sebastian的最終概念模型



Sebastian表面材質參考



Sebastian面具表面材質參考

Lieutenant / Lu

有一點很重要,Lu 不只是一名下屬,我們更希望她是合作夥伴。這名戰士和Sebastian等同於精神領袖。與Sebastian不同的是,Lu的體態更輕,行動更敏捷,但同樣令人生畏。

Lu早期頭部草圖


概念造型及裝備坦克鏈條的線稿








警衛隊

最初我們給衛兵起了綽號叫“醫生哨兵”,希望反映出設計背後兩個簡單的想法。城市的警衛是少數能傳達高牆內文明的機會之一。在某種程度上他們成為這個城市和日漸衰退文明的人類象徵。他們被設計為包覆嚴實的雄性純粹主義者,在面臨同類日益減少的情況下拼死維護自己的身份。





警衛服的初稿


警衛服最終設計


警衛的武器和裝備
,繼承了醫學出身的軍國主義風格



牢房

最初的想法牢房是整個故事的起點,也是Adam的“誕生地”。因此為了發揮它的重要性,我們經過了大量的反覆計算,直到最後關鍵的要素都達成我們想要的平衡。
我們希望它是一個幽閉恐懼的空間,並且能延續類似開刀房的氛圍,我們嘗試了類似於機械子宮的東西,並在裡面放了許多腸狀的管道通往四面八方的空間。

最初的一些參考,包括狹窄的引擎室,引擎橫截面和潛艇內部




尋找表達的方式

下面是製作改造牢房牆壁的縮圖。這時已到專案後期,那時我們已經有了基礎幾何圖形模擬的房間,並已設定好相機和動作捕捉,只需擷取我們想用的元素即可。


3D 草圖

除了最初參考的草圖和縮圖,大部分實際的環境設計都是在Maya上完成的。所以我們直接在Unity引擎上使用這些環境,測試包括空間、結構和距離,在早期我們就能自由的反覆運算電影各方面進行迭代。甚至有些模型效果很好,直接在最終版本都還用到。




高牆

最初的想法城市高牆設定的主要是表達出高牆後面的社會生活本質。在此也彰顯出城市的醫療風格和其影響力,牆面設計粗獷簡單就像是排列整齊的醫療檔案,從而將牆壁打造成資料夾風格,好似記載著日漸消失的人性在醫學或生物學上的記憶。



尋找表達的方式




最初的預覽圖,這些都是非常早期的概念,定義了大部分關鍵物體的位置和外觀



瞭望塔是在很後期才加進去為了讓高牆更豐富,一開始就加在現有建築物上,後期再完善




城牆和平臺粗模。大部分外景設計完成粗模並進行了多次反覆改進






粗模上方的一系列模型繪製,幫助製作地形的美術完善細節




不斷修正牆面細節,並完善所有要素和貼圖



荒野及斷裂的公路

最初希望陌生人和Adam及其他罪犯在這斷裂的公路相遇,我們想將它打造成一個有神聖感的地方:不經意出現的寺廟。我們將一截破碎公路對稱擺放來創建神殿般的背景。這個設計深受Hiroshi Yoshida的版畫作品《In A Temple Yard》的影響。



概念藝術


最初,我們設定 Sebastian 和 Lu 出現在山谷平坦的泥濘中,橫越正在融化的冰湖。為實現兩人水上行走的效果,我們採用了小角度拍攝


關於外部空間。角色最初的想法是從深邃、陰冷的牆內轉到太陽下。但最後放棄了這個想法,因為很多的外部鏡頭都受到了燈光的限制




後來的兩個鏡頭我們研究地面的細節分佈以及地平線的懸崖分佈和形狀也
嘗試了很多做法

待續......

關於我自己

我的相片
Unity台灣官方部落格 請上Facebook搜尋Unity Taiwan取得Unity中文的最新資訊