Unity中簡單的優化物理系統

2021-02-20 Unity牆外的世界

這個篇文章的主要目標是給予你一個關於在Unity中簡單的優化物理系統

我的遊戲物理系統有什麼錯誤嗎?

怎麼去處理遊戲物理系統?

Unity 物理系統有什麼缺陷嗎?

Unity 是怎樣處理物理系統的?

我在 Unity 物理系統上做了什麼控制?

在我開始使用遊戲物理系統之前我應該關心什麼事情?

我應該在時候避免使用物理系統?

我看到了幀速率在下降,這是否是物理系統導致的?

當涉及到物理系統時,便會有以上這些問題,或許你會有更多像上面類似的問題。

是的,是的,我知道!我們全怪那個平果,它為什麼要在那一天降臨到牛頓的頭上?為什麼呢,上帝?

物理學也許不是每個人最愛的科目,但是物理學在遊戲開發行業中真的是一個非常重要的角色。

想像一種情況,在緊要關頭你最終決定提出做一個大事情。一個讓人矚目的,一個使用逼真的物理和圖像的大遊戲。

設計已經創建出來,架構已經完成,一切看上去似乎已經準備就緒。但是你最終坐了下來,開始在最棘手的部分上工作,「物理系統」!!

此時,似乎所以東西都崩潰了;你無意中看到了很低的FPS,奇怪的移動,碰撞器/觸發器 出現了問題,高CPU使用率等等。

不恰當或者不正確的使用物理系統可能會把一些遊戲玩家嚇跑。這不只是關於不恰當的使用物理系統的問題了;這是關於一個遊戲可玩性高不高的問題了。

這些都是不容易解決的問題。物理系統是遊戲開發過程中最困難,也是最重要的一部份,這是無法避免的!!

人們可能會說:「好的物理系統需要一個超快的CPU!」。

但是,請相信我,這句話不一定都是對的。多數情況下,可以通過由淺入深進入Unity的海洋中學習Unity 的物理系統是怎樣工作的,以便我們實現更好的物理系統。

在我還是一個程序小鮮肉的時候,我便要處理100多個與物理相關的事情。這讓我花了近一年的時間記錄下了處理物理相關的關鍵點。

因此,我決定寫這篇文章。幫助大家跳躍這個學習階段的痛苦,成為一個專業的物理系統開發者。

我不打算講關於物理系統在Unity中是如何工作的,然而我將會在怎麼優化你的物理系統中列出技巧和要點。所以,如果你是一個新手,我建議你先去大概了解一下Unity 物理系統。

物理學是一個非常非常龐大的、廣泛的概念,我決定分成不同的部分,儘可能做到簡單。

接下來,這是一個漫長有趣的過程,請你趕緊系好你的安全帶,讓我們開始吧!

在Unity文檔的說明如下:

「一個不受幀速率影響的時間間隔,用於指定在 FixedUpdate() 函數中執行物理計算每一幀的時間間隔」

默認值為 0.02(每秒),這顯示了每 20ms(毫秒)物理更新將會被執行一次。所有 FixedUpdate() 也會每20ms調用一次。

你需要不停的改變這個值,以獲得理想的效果。

例如:

「如果你打算做一個簡單的卡牌遊戲,這不需要使用太多的物理系統。然而最好減少調用物理引擎的次數。但是這操作要很細心一點;如果你減少過多的物理引擎調用的次數,你也許不會得到你想要的物理效果。」

讓我們通過下面的案例更好的理解 Fixed Timestep 吧!

步驟 1) 創建 3-4 個 球體。讓他們保持一些距離:

步驟 2)創建物理材質(通過在Assest文件夾中按下右鍵->Create->Phycics Material),並且設置摩擦係數(Friction Amount)的數值為 0 ,然後設置彈力係數(Bounciness)為 1,再設置彈力混合(Bounce combine)為最大值:

步驟 3)將該物理材質添加到球體碰撞器的物理材質卡槽中去:

步驟 4)為球體添加剛體組件(這將意味著此物體時物理對象):

步驟 5)創建一個平面,並且為其創建一個物理材質(先使用默認值),添加到平面上:

步驟 6)讓創建的球體位於平面的上方,並且設置球體的重力選項盒為勾選狀態。

步驟 7)點擊 Play 按鈕,並且查看一下結果。

這個球在做一下一上的動作。(不好意思,汙了一下下。)

那麼,這與固定時間步(Fixed Time Step)有什麼關係呢?

上面只是一個簡單的設置,現在我讓我們開始玩耍 Fixed Time Step 的值吧!

找到 Edit>>Project Settings >> Time,在那裡,你能找到 Fixed Time Step ,它的默認值為 0.02 (正如我之前提到的那樣)。

現在讓我們設置它為 0.1,然後按下 Play 按鈕開始遊戲。

你有發現有什麼不同嗎?

首先你會注意到,這些球的運動非常的慢。

然後,你會看到球體穿過了平面而不是反彈回來。

你會問為什麼?(不需要彈跳如此的快呀!啊哈哈)

好的,如果你設置 Fixed Time Step 為 0.1,這就意味著物理更新將在每100ms(毫秒)執行一次,這很快就會注意到,將無法檢測到碰撞。

這表明,過多的降低 Fixed Time Step 的也是不恰當的。現在讓我們改變 Fixed Time Step

的值為一個更為實際可行的值 0.03 - 0.04。(具體根據球體的需要來定)

現在,如果你開始遊戲,你不會看到任何改變。只要看上去還行,那就OK。如果你細心的檢查一番,物理碰撞檢測會有一點點不同的。

看看下面的圖片:

如果你不能跟上步驟來,那麼請你參考一下Unity的官方文檔。適當的理解 Unity 物理引擎是必須的。

物理碰撞檢測會有點延遲,只會在當前幀結束之後才反彈回去。

這在你遊戲處於正常FPS下可能觀察不到,但是這可能會影響到物理效果。但只要你的需要滿足了,這也是沒什麼關係的。

這將有什麼幫助呢?

任何時候你從物理計算中節省下來的計算資源,都可以讓給渲染和其他計算密集的處理,所以就可以讓你的遊戲更加出眾。

通過設置 Maximum Allowed Timestep 在物理系統中保持檢查!

在Unity文檔中的定義如下:

「一個不受幀速率影響的時間間隔,當幀率為最低峰值的時候,物理計算和 FixedUpdate() 事件將不會被執行」

那麼,這意味著什麼呢?

讓我們先在正常的遊戲下,去理解它(Maximum Allowed Timestep)。

如果你的遊戲在運行的時候能保持在 60 FPS,這就意味著每一幀會執行 0.01666秒。意味著每一幀需要花費 16.7ms(毫秒)。

現在,讓我們把 Fixed TimeStep 設置為 0.01,這表明物理更新將每 10ms 執行一次。

這表明,在每一幀中至少會調用一次物理更新,因為 10ms<16.7ms. 現在讓我們假設由於某種原因幀率降低到了 30 FPS。

那麼,每一幀將會執行 0.0333秒(也就是33.3ms) 。也就意味著在每一幀中會調用3次物理更新(因為一次物理更新花費10ms)。這意味著如果幀率繼續下降,每幀內的物理調用還會更多。

這將會導致程序崩潰。為了解決這個問題,下面引入 Maximum Allowed TimeStep。

它的默認值為 33ms(可能是作者搞錯了,明明就是0.33333秒 = 333。33ms啊)。正如 Maximum Allowed TimeStep 定義:每當物理更新超過指定的時間,物理更新將會停止。因此,這便為其他進程節約了資源。

在我們的案例中,如果每一幀執行時間增加到 40ms,這將會調用更多的物理更新。

但是現在我們設置 Maximum Allowed TimeStep 為 0.033,也就是33ms ,物理更新將會在 33ms 後停止調用,也就是執行3次物理更新後,便會停止調用,儘管每幀的執行時間超過 50ms 也會如此。

因此為其他沉重的進程節省下一些資源。

這聽起來非常的棒,不是嗎?

但還是有會一些限制的負面影響。每當發生性能故障,動畫和物理便會放慢(意味著畫面卡頓,延遲)。

因此,要牢記Maximum Allowed TimeStep 同樣是一個重要的因素,如果使用得當,將會得到非常好的效果。

總是有 1-1-1 的比例

放大一個沒有物理的對象是沒有問題的(就是沒有與物理相關組件的物體對象),但是當一個物體時一個物理對象時,我建議你不要對該物體進行縮放。縮放會導致奇怪的碰撞檢測,也會影響到物體的下落方式。

例如:

「一塊大石頭在沒有任何空氣阻力的情況下會很快的落到地面上(如從塔上或其他地方掉下來)。但是如果它周圍的物體都放大了,那會讓下落看起來速度很慢」。

還有一個選項是調整重力加速度的值讓他看起來變得正常,但是這不是最正確的做法。正確的做法應該是保持使用1-1-1的縮放比例,因為Unity的物理引擎在這種情況下工作的最佳。

給你的對象設置恰當的質量

和縮放一樣,質量也需要保持精確。

讓一架飛機的質量為 1kg 正確嗎?

如果你考慮到度量系統準則,Unity的 1 個單位等於 1 kg 質量。同樣的,Unity的 物理系統是無量綱的。但是,如果你假定 Unity 的一個單位的長度為米,那麼,一個質量的單位為 kg。

你可以得到更完美的結果。並且,Unity在努力解決高浮點數問題,所以儘量削減取值範圍是比較理想的解決方案。

這意味著,如果假設你的飛機重 1kg ,那麼你的輪子必然不會超過 1/1000 kg。

儘可能避免使用網格碰撞器(Mesh Collider)

對任何物理引擎來說,基於網格的碰撞檢測都比原始的碰撞檢測需要更多的計算量,這是一個事實。Unity在內部使用了 Nvidia 的 PhysX,因此這是沒有什麼不同的。

一般來說,

「對於不同碰撞檢測的相對成本從高到低的排序為:三角形網格、凸包(具體可以百度百科)、膠囊體、球體、盒子(六面體)、平面、點」

通常,網格碰撞器(Mesh Collider)被標記為凸包(也建議大家這麼標記),它將被限制到255個三角形。只有在兩個網格碰撞器被標記為凸面(Covex)時才能相互發生碰撞檢測。

在 Unity 文檔中的說明:

」使用網格碰撞器時會有一些限制。沒有標記為凸面(Convex)的網格碰撞器只支持在一個沒有剛體組件的遊戲對象(GameObjecet)上發生碰撞,如果你想要在一個剛體上使用一個網格碰撞器,這必須要標記為凸面「

理想情況下,應該儘量避免使用網格碰撞體,因為他們會比傳統的碰撞器(球體,立方體,膠囊體)帶來更多的計算負載,所以最好還是少用。替代方案是什麼呢?

一個簡單的替代方法就是讓對象的子物體使用原始(傳統)碰撞器把它們組合起來(如上圖所示)。這樣會減少一定的計算量,因為原始(傳統的)碰撞器計算速度比較快。

對於複雜的網格,你通常可以使用 Blender(小巧的建模軟體)或者其他工具來將它們分解成一些小部分。然後可以用傳統碰撞器直接替換掉這些小部分的網格。

我希望我已經給你一個確切的優化描述,但是不幸的是,每個網格都是不一樣的,對於我給出一個確切的描述是非常困難的。

這個列表會很長,而且看上去會沒有盡頭,所以讓我們先休息一下,後續的博客會繼續介紹其他的提示。同時我也不希望你一下看太多關於物理的東西而產生不適。請繼續保持關注,然後先從上面幾個點開始優化。如果你有更好的替代方案,請也和我們分享一下。如果對上面討論的內容有任何問題,或者有任何疑問,請在評論區留言,我會很高興能提供任何幫助。

總結:該篇文章大體講了一下幾個關鍵字:Fixed TimeStep、Maximum Allowed TimeStep、Mesh Collider、Convex。

這些東西都能在官網組件手冊中找到一些詳細的說明,如果看不懂該文章所說的內容,還請大家自行去看一看官網的組件手冊(還記得我給你說的 Unity 聖典嗎

想看原文的,請點擊下方的原文連結。

Unity牆外的世界 --- 這裡有國外的經典案例、教程、文章,在這裡你將會學到更為先進的Unity開發知識。


更多經典,敬請期待

相關焦點

  • Unity 實用技巧 - 物理系統初識
    Unity中實際上有兩個獨立的物理引擎:一個用於3D物理,另一個用於2D物理。
  • Unity基礎之物理引擎
    我們在unity裡面建了一個正方體cube , 要如何使這個cube可以跟現實中的物體一樣受重力呢 ? 這就需要用到Rigidbody(剛體)組件了 .單擊cube , 在右邊的Inspector面板添加Rigidbody組件添加完Rigidbody組件後,cube1就可以受重力影響了,運行unity時,cube1會因為受到重力往下落.下面為大家介紹 Rigidbody 組件常用參數 : 1. Mass : 物體的質量 .
  • Unity高級知識點總結:性能優化與圖形渲染進階
    4、更多的細節優化。比如lua到C#的調用。一些頻繁調用的接口,能用簡單類型做參數,就不要弄一個結構體出來。xlua有針對這裡做NoGC的性能優化。5、緩存,預加載特效。兩個預加載時機,遊戲初始化的時候,或者技能模板初始化的時候。(四) 內存的性能優化1、壓縮紋理的使用。2、合理的釋放不必要的資源。引用計數。
  • 使用Unity 粒子系統實現 2D 人物足跡效果
    )中的示例控制腳本改進而來。之後深入一想腳本大概要怎麼寫,感覺頭大的不行,又想到了 Hierarchy 裡面被 FootStep12345678 塞得滿滿當當的壯麗場面..還是換個方法吧 轉念一想:unity 的粒子系統似乎可以滿足所有特性:生成淡出銷毀全自動,跟隨人物也是基本操作,比較存疑的就是用腳本控制粒子的鏡像與旋轉。
  • unity實戰之大主宰
    然後回到unity,點擊windows ->package manager,就能找到自己的資源,全部import這裡是獲取場景後的結果:對象的加載簡單加載最簡單的加載方式,就是直接用滑鼠把對象拖到左上角的窗口中,然後手動設置屬性。但是這樣會耗費大量的時間去加載。(如果有許多個對象是相同的,系統會重複加載,耗時)而且有許多對象是在遊戲中途才生成的。
  • 簡化AR體驗創作,Unity MARS Query系統程序化生成場景的原理
    平面尺寸條件:  https://docs.unity3d.com/Packages/com.unity.mars@1.1/manual/GettingStarted.html?  每個代理默認都帶有一個最簡單的行為,即設定姿態(Set Pose)行為。該行為類型為姿態(Pose)的pose特徵為依據——即在空間中的位置與朝向。行為可用於排除不帶姿態特徵的數據。  在查詢到匹配對象後,Set Pose行為會接收對象的姿態參數,將虛擬內容放置到該位置上,匹配的查詢結果就會正確放置到環境中了()。
  • Unity項目開發過程中常見的問題,你遇到過嗎?
    否則,對項目的優化將無從談起。資源標準不明確開發過Unity項目的同學可能都有過類似的經歷,即開發過程中的資源標準不明確。這常常也是早期在項目規劃時沒有重視資源標準導致的。所以在項目的早期階段,最好能夠明確資源標準比如模型的vertex數量、紋理資源的尺寸格式等等。
  • Unity3D 尋路系統
    一、尋路方式二、實現尋路方法確定尋路者烘培尋路路面程序實現尋路算法1、實現尋路步驟將場景中不動的物體勾選
  • 王者榮耀是怎樣煉成的(三)unity組件與腳本
    這回我們來侃侃unity中的組件與腳本。一.組件與腳本簡介1.組件組件(Component),顧名思義,就是遊戲物體的組成部件。這和我們對現實生活的認識是一致的。就比如說一臺主機,是有CPU,顯卡,主板,內存條等等組成的。這些部件就是主機的「組件」。這些組件一旦有不滿意的,隨時可以增刪改查。
  • Unity技術分享(100)| Texture2DArray、粒子系統的性能開銷……
    今天,我們繼續為大家精選了5個和開發、優化相關的問題,建議閱讀時間15分鐘,認真讀完必有收穫。如果您有任何獨到的見解或者發現也歡迎聯繫我們,一起探討。UWA QQUWA 問答社區:answer.uwa4d.com粒子系統Q:請問粒子系統的消耗如何區分呢?哪部分是在CPU哪部分在GPU呢?
  • unity業餘愛好者說一下
    unity業餘愛好者說一下,這幾天傳的關於《太吾繪卷》代碼的事幾乎都是無中生有的事...一群用.net和vs做工程的人談論第三方引擎做的遊戲...真是雞同鴨講。太吾繪卷現在針對幾個常見誤會說一下1.只有一個main (x)unity的腳本都是依附於各個精靈的,沒有main,只有update2.沒有注釋(x)你反編譯出來的代碼有注釋
  • Unity粒子系統小技巧X1
    幾個方法都是用unity粒子系統裡面的Velocity over lifetime(不知道這是什麼的去學基礎課)第一個方法是給一個和一開始相反的速度讓粒子回去它出來的地方C部分,是讓粒子在外面停留A部分和B部分的比重是差不多的,這樣才能保證粒子出去後回到正確的地方我們可以看到C部分的兩條曲線中間有個縫隙,那是因為兩條曲線的數值並不是0,而是0.01和-0.01這麼給的原因是可以讓粒子在外面停留的時候是一個緩動的狀態,而不是完全靜止好了第一個方法講完了,是不是很簡單呢
  • 【官方說明】Unity 5 引擎專業版和個人版解析
    最新Unity 5的Professional Edition(專業版)具備全新而強大的功能,除了全局動態光照或是最新的基於物理的著色器之外,也把原本分開銷售的Team License放入,並含有12個月的Unity Cloud Build 和Unity Analytics 授權,價格只要1500美金一套或是月租75美金。
  • unity 半透明渲染技巧(3則)
    所以這裡只分享些個人針對一些具體開發積累的小小技巧(持續補充中...)。對於 為什麼會出現這個問題本質原因還不清楚的 可以看這篇基礎說明(文章底部參考閱讀). 理解這個基礎原因很有好處,否則一堆美術問你為什麼max maya 沒問題 unity ue有問題的時候 你不知道怎麼回答。
  • Unity編碼篇 Rigidbody類
    Rigidbogy組件可以使遊戲對象在物理系統的控制下運動 , 發射一顆子彈 ,如果子彈沒有命中任何物體 ,最後 子彈會因為重力落下 , 此時就可以利用 Rigidbody 組件實現 , 但是使用該組件一般在 FixedUpdate 函數中執行 , 因為物理仿真一般都在固定頻率下進行計算的 .
  • 虛幻引擎4.32版發布 加入光線追蹤優化和物理破壞系統
    虛幻引擎4.23版本更新現已發布,這是一個比較重要的更新,最主要的是新增了「混沌」物理破壞系統。Epic曾在GDC 2019上公開過這一特性的技術演示。此外這個版本還優化了實時光線追蹤性能。更新說明:新增:「混亂」破壞系統(Beta)- 「混沌」是虛幻引擎最新的高性能物理破壞系統,從4.23版本開始進行beta預覽。通過「混沌」系統,玩家可以實現電影級別的大規模破壞場景視效,對內容創建進行前所未有的藝術掌控。新增:實時光線追蹤(Beta)- 光線追蹤功能增加了優化和穩定性提升,加入了數個重要的新功能。
  • Unity2018新功能搶鮮 | 粒子系統改進
    洪流學堂,讓你學Unity快人幾步Unity2018.1中對粒子系統進行了重大改進,包括功能、性能很多方面,快來看看吧!GPU網格實例化粒子系統現在支持GPU實例化來渲染網格。粒子系統使用Procedural Instancing,可以在此處詳細解釋:https://docs.unity3d.com/Manual/GPUInstancing.html實例化支持已添加到「Particle Standard Shaders」中,並將在所有新內容中默認啟用。舊版內容升級到Unity 2018.1後,可以使用Renderer模塊中的複選框啟用GPU實例化。
  • Unity 最新版本迎來260項功能改進,高清渲染管線HDRP升級
    貼花著色器(Decal Shader)可將貼花貼到場景中的表面上,同時支持投影貼花和網格貼花。資源包還支持以下高級光照效果:物理光照單位。HDRP中所有的光照類型,以及天空和發光屬性,都使用物理光照單位來實現逼真的場景畫面。物理光照還能更輕易地實現一致的光照,改善綁定場景光照的工作流。
  • unity什麼意思
    unity什麼意思uni前綴,只包含一個的,更多例子還有:uniform, unique, unilateral, etc. 發音類似於有你,整個世界中有你就夠了,不需要別人,也就是只包含一個的。unity,聯合、統一、團結、和睦。學單詞,只記住意思可不行,會用才行,小夥伴們可以在評論區造句,我們一起學習哦!我先來:造句:Unity is strength. (團結就是力量)
  • Unity 2018.3 Beta版發布
    直播課程:Facial AR Remote面部捕捉解決方案課程(第一期)直播地址:https://connect.unity.com/events/unitychina-facialarUnity官方教師培訓報名火熱進行中Unity將在10月22-26日,舉辦為期5天的專業的Unity官方教師培訓課程,誠邀廣大教師與