Unity 3D物理引擎使用的是已經(jīng)開源的PhysX粤剧。下面是這幾天學(xué)習(xí)的筆記奕污。
碰撞
參與碰撞的對(duì)象
參與碰撞的對(duì)象有3種:
- 靜態(tài)碰撞器(有Collider沒有RigidBody)
- 剛體(有Collider有RigidBody)
- 運(yùn)動(dòng)學(xué)剛體(有Collider有RigidBody并且RigidBody的參數(shù)Is Kinematic為true)
注意:子物體有Collider就算有Collider,掛載RigidBody組件的對(duì)象不一定要有Collider按厘。
參與物理碰撞的對(duì)象必然是上面三種對(duì)象之一医吊。
靜態(tài)碰撞器最好理解,不想移動(dòng)但需要參與碰撞的物體(場(chǎng)景中的障礙等)逮京,不會(huì)因?yàn)榕鲎舶l(fā)生位移卿堂。
剛體理論上是完全依靠物理系統(tǒng)驅(qū)動(dòng)的對(duì)象,剛體有專門的位移方法(AddForce懒棉,MovePosition或者直接指定速度)草描,不要直接設(shè)置Transform,否則你會(huì)發(fā)現(xiàn)物體的運(yùn)動(dòng)跟你預(yù)想的不同策严。
運(yùn)動(dòng)學(xué)剛體我更愿意理解為可以調(diào)整Transform但同時(shí)又可以參與碰撞的對(duì)象穗慕。他可以通過設(shè)置Is Kinematic在普通物體和剛體之間切換。
運(yùn)動(dòng)學(xué)剛體的應(yīng)用場(chǎng)景(官方舉例): - 布娃娃系統(tǒng):通過Transform控制動(dòng)力學(xué)剛體的位移妻导,在碰撞發(fā)生后設(shè)置 Is Kinematic為false逛绵,這樣這個(gè)物體就會(huì)發(fā)生碰撞(飛出去)。
- 門:通常情況下是不會(huì)動(dòng)的(運(yùn)動(dòng)學(xué)剛體)倔韭,但是需要的時(shí)候可以被打開(碰撞后改成剛體术浪,有真實(shí)的運(yùn)動(dòng)效果)
休眠和喚醒
首先休眠與否是針對(duì)剛體而言,靜態(tài)碰撞器沒有休眠一說寿酌。對(duì)于已經(jīng)休眠的剛體胰苏,物理系統(tǒng)將會(huì)停止對(duì)他們的計(jì)算。
進(jìn)入休眠的幾種方式:
- 速度小于一定的值醇疼,跟剛體是否受力無關(guān)硕并。
- RigidBody.Sleep()法焰。注意這個(gè)方法只能讓剛體休眠一幀,但是是否可以一直休眠下去倔毙,就要看下一幀物理系統(tǒng)檢測(cè)的時(shí)候判定該剛體是否能進(jìn)入休眠壶栋。
對(duì)于第一條,進(jìn)入休眠的特定速度是可調(diào)的普监,可以通過Project Setting/Physics里面的Sleep Threshold設(shè)置,注意這個(gè)值不是指速度低于這個(gè)值會(huì)休眠琉兜,而是物體的動(dòng)能除以質(zhì)量小于這個(gè)值就會(huì)休眠凯正。
下面放個(gè)動(dòng)能公式:
Sleep Threshold的默認(rèn)值是0.005,即默認(rèn)速度小于0.1的時(shí)候會(huì)進(jìn)入休眠豌蟋。
休眠的目的是節(jié)省物理系統(tǒng)的一些開銷廊散。
可以通過以下幾種方式喚醒剛體:
- 給剛體施加力,包括摩擦力等梧疲。比如和另一個(gè)物體發(fā)生碰撞允睹。運(yùn)動(dòng)學(xué)剛體即使通過Transform移動(dòng),也一樣可以對(duì)其他剛體施加力幌氮。
- RigidBody.AddForce()缭受。本質(zhì)上也是給剛體施加力。
- RigidBody.WakeUp()该互。
移動(dòng)靜態(tài)碰撞器不會(huì)喚醒已休眠的剛體(實(shí)際測(cè)試的時(shí)候發(fā)現(xiàn)還是有可能喚醒剛體的米者,不過結(jié)果有不確定性)。
運(yùn)動(dòng)學(xué)剛體也會(huì)休眠和被喚醒宇智,通過Transform移動(dòng)它就可以喚醒蔓搞。
碰撞行為矩陣
上圖是unity官方總結(jié)的是否可以發(fā)生碰撞行為的條件。其實(shí)可以用很簡(jiǎn)單的一句話概括:碰撞雙方必須有一個(gè)是非運(yùn)動(dòng)學(xué)剛體(普通剛體)随橘。
幾個(gè)注意:
- AddForce只能用于非運(yùn)動(dòng)學(xué)剛體喂分,對(duì)于運(yùn)動(dòng)學(xué)剛體調(diào)用AddForce沒反應(yīng)。
- 對(duì)于運(yùn)動(dòng)學(xué)剛體机蔗,可以直接調(diào)用Transform調(diào)整蒲祈,也可以通過RigidBody.Position和RigidBody.Rotation調(diào)整。通過RigidBody調(diào)整效率要優(yōu)于通過Transform調(diào)整蜒车。因?yàn)閯傮w的位移和旋轉(zhuǎn)會(huì)導(dǎo)致其下的碰撞器也發(fā)生改變讳嘱,如果通過前者調(diào)整,所有的改變將會(huì)在物理系統(tǒng)里一次性處理酿愧,而后者不在物理系統(tǒng)中沥潭,將會(huì)重新計(jì)算所有的碰撞器,并再次調(diào)用物理系統(tǒng)(猜的)嬉挡。
- 如果要持續(xù)的移動(dòng)非運(yùn)動(dòng)剛體钝鸽,可以用MovePosition方法汇恤,該方法會(huì)根據(jù)插值的設(shè)置進(jìn)行更平滑的運(yùn)動(dòng)。不過插值的設(shè)置通常是none拔恰,官方建議只給主角設(shè)置插值因谎,因?yàn)槲锢硐到y(tǒng)和渲染不一定同步,渲染時(shí)可能會(huì)出現(xiàn)卡頓或者跳幀颜懊,插值只是根據(jù)上一幀/下一幀(Interpolate\Extrapolate)的運(yùn)動(dòng)對(duì)Transform進(jìn)行平滑而已财岔。
- 運(yùn)動(dòng)學(xué)剛體和鎖定XYZ的剛體可以觸發(fā)碰撞(有碰撞消息),但會(huì)發(fā)生穿插河爹。
觸發(fā)器
觸發(fā)器就是在碰撞器的基礎(chǔ)上匠璧,將碰撞器的isTrigger選項(xiàng)打開。
所有的觸發(fā)器都不會(huì)發(fā)生碰撞咸这,只是會(huì)收到觸發(fā)消息夷恍。
觸發(fā)矩陣
表格有點(diǎn)復(fù)雜,其實(shí)觸發(fā)器觸發(fā)的條件也很簡(jiǎn)單:碰撞雙方必須有一個(gè)剛體(包含運(yùn)動(dòng)學(xué)剛體)和一個(gè)Trigger媳维,剛體和Trigger可以不在同一個(gè)物體上酿雪,也可以在同一個(gè)物體上(比如剛體觸發(fā)器RigidBody Trigger和運(yùn)動(dòng)學(xué)剛體觸發(fā)器Kinematic RigidBody Trigger),對(duì)于在同一個(gè)物體上的觸發(fā)器侄刽,就可以跟任何觸發(fā)器/碰撞器觸發(fā)了指黎。