天天看點

【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

說在前面

首先,作為尊敬這位大神的工作成果,貼出原帖的位置:

http://forum.unity3d.com/threads/how-to-make-a-physically-real-stable-car-with-wheelcolliders.50643/

(請大家搬運轉載的時候,尊重原作,連同上面資訊一起轉載。不僅是誠意貼,而且WheelColliders的文獻有幹貨的真的難找。。)

翻譯水準有限,也請各位讀者海涵。如果各位想了解WheelCollider怎麼使用,可以參照Car Physics示例(連結:http://pan.baidu.com/s/1kTjIQ4f 密碼:02n9)。本篇不對基本使用方法做叙述,側重怎樣調整WheelCollider與程式配合表現出真實效果。

轉載請注明,出自喵喵丸的部落格 (http://blog.csdn.net/u011643833/article/details/49102423)

搬運正文

【下面出現如這個形式與顔色的部分為我自己添加的注釋】

Part1 Demo說明以及幾條建議

Demo位址:http://www.edy.es/dev/vehicle-physics/live-demo

【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

Enter——重新開始,當你翻車或者跑出了Terrain

H——擷取幫助【我發現原帖中介紹的按鍵有些已經不是他曾經說明的功能了,是以大家還是點開H,檢視按鍵說明(在回帖中發現是論壇不容許貼主編輯原文,是以把相關更新都寫在了回帖中,我也相應的解除安裝了回帖總結的部分裡面)】

【另外:提供了幾種車輛常用的系統,我粗略試了一下TC和4x4/rear(剩餘應該也可以工作),其餘的幾種隻因為我不太了解工作起來的表現,隻能請各位自己試試咯~

ABS:防抱死、TC:循迹防滑控制系統、ESP:電子車身穩定系統、 4x4/rear:四驅/後驅】

【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

Demo中示範的不僅是一個典型公路車不太平穩的樣子,而且在背後負重了一直500KG(1100磅)重的盒子。你可以嘗試在Demo中的各個地形上行車使這個盒子保持不掉下去。【這是進入Demo後的第一個示範車(越野車)的狀态,Demo中還有跑車以及公共汽車的示範】

建議Notes:

  • 車子的簡單實體模型:剛體Rigidbody + 基于車子形狀的組織的一些BoxCollider + 4個wheelCollider
  • RigidBody的centerOfMass的設定在車子的前座附近【Rigidbody.centerOfMass 品質中心 相對于變換原點的質心。如果你不在腳本中設定質心,它将從所有附加到剛體上的碰撞器自動計算,當模拟汽車使它們更加穩定時,設定質心是非常有用的。具有較低質心的汽車不太容易翻車。】
  • 不要設定剛體RigidBody上AngularDrag(角阻力), 不要給車子設定其他作用力
  • WheelCollider中輪胎的摩擦系數使用預設值,隻調整 Forward Friction/Stiffness Factor(正向摩擦/剛度系數)以及Sideways Friction/Stiffness Factor(橫向摩擦/剛度系數),分别為Forward0.82、SideWays:0.022
  • 運作時不修改任何參數,不論是Rigidbody.centerOfMass(品質中心)、rigidbody其他參數、wheelCollider的suspension(懸挂系數)還是其他的參數

Part2 WheelCollider使用常見問題分析

Q:一部用剛體Rigidbody和4個WheelCollider構成的的車,在轉彎時為何特别容易翻車

A:因為現實生活中的車,就是這麼容易翻!

在Unity中建立的車子填充了真車的資料(品質、尺寸等),添加了控制車輛的腳本跑起來的那一刻,你就會發現,一點點的速度就會使你的車在拐角處輕易的翻車。如果同樣的車可以出現在現實生活中,也會是同樣的表現。PhysX并不完美,可是他可以相當好的還原與真實物體類似的實體行為。

你可以建立一個WheelCollider觀察他的摩擦曲線參數Friction,裡面的參數預設為(1,20000,2,10000,1),這幾乎是無限抓地力的一組輪胎系數,是以當車子運動起來隻能是較低的速度,是以首先要做的是,将Stiffness Factor剛度系數調整到0.01-0.03之間,這樣輪胎會更像現實中的表現。但是在這種情況下,還是會翻車。

【這裡提供三個wheelCollider說明的網址

WheelCollider說明(中文)

WheelCollider說明(UnityManual)

WheelCollider使用指引(UnityManual)】

Q:但是現實中的車為什麼并不像你說的那麼容易就翻?

A:因為現實生活中的車有一種叫做平衡杆(又名防側傾杆或防搖杆)的裝置

首先來科普一下,平衡杆是怎麼工作的(依舊是英文文獻。。)【這時候就勇敢的去百度一下平衡杆】

當現實生活中的車發生急轉的時候,車輛的外側輪胎向下貼近路面,車輛的内側輪胎被擡高。換一種說法,這時的車子向着外側旋轉了10°、20°或者更多。如果這時車的速度夠快,這種向着外側發生的旋轉就會引起翻車,這種情形是否和你剛才做過的翻車實驗很像?

穩定杆連接配接了同一根軸上面兩個輪胎,限制這兩個輪胎之間的自由度。當一側的輪胎擡起的時候,平衡杆會将力分解到另一側的輪胎以及懸挂系統之上,這樣就限制了車身在這個軸向上的旋轉。

如果沒有平衡杆,車身會在轉彎發生的時候發生翻車,如果平衡杆做的太過,那麼兩側的懸挂系統又會失去獨立性。

Q:平衡杆什麼的根本沒聽過,真的這麼重要麼?

A:當然,平衡杆是車輛懸挂系統的重要組成部分,和車子的彈簧和阻尼器一樣重要。

你可以觀察一下現實中車子的前輪内側,你可以看到一個連接配接兩端懸挂系統的剛性杆,這就是我們說的平衡杆。現實中隻有很少的一部分車子使用了類似液壓控制系統的動态系統來模仿實作平衡杆的作用。

在Unity中使用WheelCollider,其實有官方的文檔做了一些使用示範,可是穩定的WheelCollider應該包含怎樣的參數内容,以及平衡杆相關内容幾乎沒有提及。

Q:那麼之前提及的建議(更低的質心,角阻力,自定義的輪胎摩擦系數…)有何作用?

A:就是為了讓你的車變得像是安裝了平衡杆一樣的基礎條件。

當你真正的有一輛具備了剛體Rigidbody + 4個WheelCollider + 2組平衡杆(前輪後輪各一組)的車子,你才可以在技術上對你的車子進行其他方面的調整,比如手感、或者其他駕駛風格的車子。

你會發現即使是構成上如此簡單的一部車,也會有很多可以調整和選擇部分,這些都可以幫助你創造出不同手感和駕駛體驗的車子,舉例說明一下:品質Mass、質心位置centerOfMass(通常會向發動機所在位置放)、前後輪彈簧系數Spring、前後輪阻尼系數Dampers(前後輪必須不同,引擎所在的軸需要提供更多的支撐力)、前後輪的剛度系數Striffness…

你可以把複雜的摩擦系數、阻力系數留到最後再考慮,這樣你可以看到隻調整前後輪的剛度系數Striffness,會對平衡杆造成的影響,進而造成的手感不同。

Q:質心CenterOfMass的降低,會帶來什麼不利的影響

A:會使得跳躍、碰撞、撞擊和空中的姿态看起來奇怪一些

利用手動設定質心的方式會使得某一些運動的情況變好,但是另外一些情況下顯得奇怪起來。如果你調整了質心CenterOfMass,使得它更趨近真實,平衡杆的效應會使得所有的運動情況都趨向于真實。

Q:你說了這麼多。可是我在運作Demo的時候,跑車模式下轉彎翻車了!

A:如果你在現實中開了這樣一輛車,并在高速模式下轉急彎。你真的會像是Demo裡一樣的翻車的。

如果你看過一些關于車子紀錄片,你會明白這類跑車即使在正常的速度下也很容易翻車。你可能知道一種叫做麋鹿測試(The moose test)的東西【此處可百度麋鹿測試,有圖示】,以80km/h通過密集的S彎道,現實中有很多車都沒能通過這個測試。

而且,Demo中車子質心CenterOfMass的高度是位于車高一半的附近!如果你想讓他在“賽車”模式之下翻車,你需要在60Km/h的速度下進行急轉,這種情況才翻車,平衡杆已經起到了很大的作用了。

【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

Part3 幹貨

Q:Unity裡如何模拟出平衡杆呢?

A:很容易(。・∀・)ノ゙

平衡杆的工作方式将力是從一側的彈簧傳遞向同一軸另一側,傳遞的量取決于兩輪之間懸挂的差異。

是以首先需要計算在地面以及不在地面時每個輪子不同的懸挂變化。我們期望變化的值在0.0(完全壓縮)與1.0(完全擴充)之間

groundedL = WheelL.GetGroundHit(hit))
if (groundedL)
    travelL = (-WheelL.transform.InverseTransformPoint(hit.point).y - WheelL.radius) / WheelL.suspensionDistance;
else
    travelL = ;
           

我們将平衡杆彈簧可傳遞的最大的力稱為平衡杆剛度系數(即:下面代碼中提到的變量AntiRoll),接下來我們将軸兩端懸挂差異的值與平衡杆的剛度系數想乘,計算結果即是平衡杆傳遞的力的大小。

最後,我們需要将計算出來的力從一側減掉,并且添加到另一側的輪子上。這個過程我們通過從輪胎Wheelcollider所在位置向剛體Rigidbody添加反向作用力來實作。

if (groundedL)
    rigidbody.AddForceAtPosition(WheelL.transform.up * -antiRollForce, WheelL.transform.position);
if (groundedR)
    rigidbody.AddForceAtPosition(WheelR.transform.up * antiRollForce, WheelR.transform.position);

           

Q:平衡杆的剛度系數(AntiRoll的值)取多少合适?他的機關是什麼?

A:合适的取值大緻是輪子的Spring的取值,機關同樣是牛頓(N)【這個地方我去翻找了一下WheelCollider中Suspension Spring/Spring 的描述,還真是彈簧力(:з」∠)是以機關為牛頓】

Spring的值表示彈簧完全壓縮的時候,能夠提供的力。而AntiRoll的值表示從一側傳遞向另一側的力的大小。同一根軸上面的Spring和AntiRoll兩者同樣大小意味着平衡軸可以将全部的力傳遞到另一邊。

Q:求一份平衡杆的腳本代碼

A:給!【貼主Edy真仁義,給出的是JS的代碼,大家有需要C#自行翻譯一下,至于代碼的意義上面巨大的篇幅已經闡述過了】

【貼主Edy覺得Unity官方将平衡杆相關的代碼加入Standard Assets内,這篇文章是2010年的,可是我15年使用4.6還沒有相關的代碼(:з」∠)是以肯定不隻我一個覺得WheelCollider用起來不知所措】

在車輛上添加兩個平衡杆腳本,前後平衡軸各一個,調整軸左右輪胎WheelCollider的參數設定與平衡杆相比對。記住要重新設定質心位置(或者完全不要動質心的位置)。

下面是完整的腳本 AntiRollBar.js

var WheelL : WheelCollider;
var WheelR : WheelCollider;
var AntiRoll = ;

function FixedUpdate ()
{
    var hit : WheelHit;
    var travelL = ;
    var travelR = ;

    //計算兩側輪胎在不同情況下的懸挂系數
    var groundedL = WheelL.GetGroundHit(hit);
    if (groundedL)
        travelL = (-WheelL.transform.InverseTransformPoint(hit.point).y - WheelL.radius) / WheelL.suspensionDistance;

    var groundedR = WheelR.GetGroundHit(hit);
    if (groundedR)
        travelR = (-WheelR.transform.InverseTransformPoint(hit.point).y - WheelR.radius) / WheelR.suspensionDistance;

    //計算平衡杆剛度系數
    var antiRollForce = (travelL - travelR) * AntiRoll;

    //向兩側的輪胎配置設定力
    if (groundedL)
        rigidbody.AddForceAtPosition(WheelL.transform.up * -antiRollForce, WheelL.transform.position);  
    if (groundedR)
        rigidbody.AddForceAtPosition(WheelR.transform.up * antiRollForce, WheelR.transform.position);  
}
           

Q:如何給車設定真正的質心

A:使用不重合的BoxCollider按照車子的形狀圍起來,然後把中心移動引擎處。

【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

Unity/PhysX的質心CenterOfMass是基于碰撞盒的位置和體積計算的,需要注意的是,重疊的Collider會在重疊部分增加多餘的品質。

通常情況下,你需要把質心CenterOfMass向發動機位置移動一些。例如:如果車子的引擎靠前并且對于車子來講前方為Z軸正方向,你隻需要将質心向前移動1m,剩下的程式會幫你自動計算。

function Start()
{
    rigidbody.centerOfMass += Vector3(, , );
}
           

Q:這麼簡單的處理真的能有良好的表現麼?

A:那麼你可以到這裡來體驗下:http://www.edy.es/dev/vehicle-physics/live-demo

你可以切換到車裡的視角觀察車子的運動、也可以觀察整體的運動狀況,等等…

【可以潇灑的漂移!而且引擎的聲音處理的也很搭。最最重要的手感十分穩定真實】

Part4 作者Edy的結語

【以下是作者Edy的一些自我介紹,不感興趣的同學可以直接跳過來閱讀下面的回帖部分】

這是我在這裡的第一次發帖,請允許我介紹一下自己,我現在工作于 dj software,幾年前,當我還是學生的時候,曾經和我的兩個同學嘗試使用C++在無引擎的情況下開發遊戲,隻因為自己從小就想要做這樣的事情。如你想象的一樣,我們幾乎沒有成果。我在4周前我發現了Unity(之前雖然聽說過,但是并沒有嘗試),這對我來說簡直是看到了光。我隻需要将我想要的東西拖入場景,點選播放,他便可以運作了!我檢視示例代碼并使用Unity用的語言進行調整(知道兩周前我才發現是JavaScript)。這簡直像是魔法,現在我正在實作一個自己從小就有的夢想——想要通過之前學習的Basic或者指令行來實作的實體真實的車輛模型,不僅如此,還可以簡單做出各種各樣的車輛體驗!即使是作為一個愛好者,出于對Unity的熱愛購買了付費版本。

這是我第一次對Unity社群做出貢獻。使用Unity車輛實體模型非常有趣。

Enjoy!

Edy

Part5 回帖摘錄

【文章過去很久了,有一部分圖檔我已經看不到了,是以,問題的一部分情況依靠腦補】

  1. 問題現象:不論mass/Spring/Damping的值如何調整,車速一直很低

    問題解決:

    ① Sideways Friction /Stiffness Factor值為1,所有車輪上面的這一項值都應該在0.01-0.02之間,微調這個值可以讓車子的“漂移”呈現不同的狀态【這裡做個說明吧,其實作者Edy前後幾次都提到了關于橫向摩擦的剛度系數Sideways Friction /Stiffness Factor取值範圍,但是每次給出的範圍都不太一樣,這裡作為我個人的猜測,這裡存在問題的車輛應該是一種以漂移為主要手感的車,是以Edy給出的範圍為0.01-0.02。我自己進行試驗的時候調整到0.01-0.02範圍内,車尾在轉彎的時候已經擺的非常大了。是以各位可以自己測試一下橫向摩擦剛度系數對自己的車子手感造成多大影響,測試時候可以按照Edy在更後面回帖中提出的從0.04開始向更小或者更大取值測試,一般不會低于0.01,也不會高于0.06太多(自己測試0.06轉彎已經非常的笨了)】

    ② 車輪的半徑Radius太大,半徑要更現實一些,大約為0.5。需要注意的是,半徑也在增加你車輛的高度

    ③ 車身的上部存在了一個過大的Collider,這使得自動計算的質心CenterOfMass将會非常高,這時需要将質心移動到一個更真實的點上,在更靠下的地方會更好。

  2. 貼主提到了Demo新的更新内容
    【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

    ① 做了許多改進

    ②變成了四輛車(皮卡/ GTA4 中的皮卡/ 公共汽車/跑車)可使用PageUp/PageDown來進行切換

    ③增添可以顯示速度、轉速、和其他行駛參數的儀表盤

    ④ 改進了碰撞變形損傷、修複的腳本

    ⑤ 視角切換為車内時,可以移動滑鼠觀察車内情況(F1切換車内)

    ⑥ 公共汽車可以使用公交司機的後視鏡視角(F1)

    ⑦ 低速時更好的模拟摩擦力

    ⑧ 漂移撞擊時候更好的煙效

    ⑨ 圖像來展現輪胎參數(B 以及ShiftB)

    【關閉TC可以在地面上漂移處帥氣輪胎印】

  3. 問題現象:讓車向前就會翻車

    問題解決:forwardFriction.stiffnessFactor 的值過高,應該在0.02-0.08之間取值。同時還需要将你設定的motorTorque/brakeTorque的值變小,不要參照真實的數值,自己調整數值嘗試直到他正常工作。

    【這裡我提供中英兩處關于WheelCollider腳本Api

    Unity聖典 WheelCollider(中文)

    Untiy Manual WheelCollider】

  4. 一個很常見的問題:當車速爬升過一定的速度之後,翻車将會變得特别容易

    Unity提供的WheelCollider存在這樣一個設計缺陷:速度變大時 SidewaysFriction将大大增加。解決方法是限制你車輛的最大速度,找到一個sideways stiffness、質心高度CenterOfMass、平衡杆剛度之間的合适平衡,這個平衡可以使得車輛在最大速度之下隻發生側滑。sideways stiffness的取值從0.04開始嘗試,最後将值固定在0.02-0.06之間,這樣這個問題就能很好的解決了。

    【一點個人猜想:GTA5中越好開(操作容易)的車越是破,豪車非常難以操控 是不是也是這個道理呢(:з」∠)(一點點猜想)】

寫在最後

歡迎各位留言指正~

再次感謝貼主Edy容許我轉載翻譯~

原帖位址http://forum.unity3d.com/threads/how-to-make-a-physically-real-stable-car-with-wheelcolliders.50643/

【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車
【Unity】【翻譯搬運】使用WheelColliders做出穩定真實的車

轉載請注明,出自喵喵丸的部落格 (http://blog.csdn.net/u011643833/article/details/49102423)