要產(chǎn)生碰撞必須為游戲?qū)ο筇砑觿傮w(Rigidbody)和(各種類型的3D/2D)碰撞器(Collider),剛體可以讓物體在物理影響下運(yùn)動(dòng).下面先講3D情況下:
兩個(gè)物體都必須帶有碰撞器(Collider),運(yùn)動(dòng)的物體還必須帶有Rigidbody剛體。
在unity3d中,能檢測(cè)碰撞發(fā)生的方式有兩種,一種是利用碰撞器,另一種則是利用觸發(fā)器.
碰撞器:一群組件,它包含了很多種類,比如:Box Collider(盒碰撞體),Mesh Collider(網(wǎng)格碰撞體)等,這些碰撞器應(yīng)用的場(chǎng)合不同,但都必須加到GameObjecet身上。
觸發(fā)器,只需要在檢視面板中的碰撞器組件中勾選IsTrigger屬性選擇框。
觸發(fā)信息檢測(cè):當(dāng)Is Trigger=true時(shí),碰撞器被物理引擎所忽略,沒(méi)有碰撞效果,可以調(diào)用OnTriggerEnter/Stay/Exit函數(shù)。
1.MonoBehaviour.OnTriggerEnter(Collider collider)當(dāng)進(jìn)入觸發(fā)器
2.MonoBehaviour.OnTriggerExit(Collider collider)當(dāng)退出觸發(fā)器
3.MonoBehaviour.OnTriggerStay(Collider collider)當(dāng)逗留觸發(fā)器
碰撞信息檢測(cè):當(dāng)Is Trigger=false時(shí),碰撞器根據(jù)物理引擎引發(fā)碰撞,產(chǎn)生碰撞的效果,可以調(diào)用OnCollisionEnter/Stay/Exit函數(shù);
1.MonoBehaviour.OnCollisionEnter(Collision collision) 當(dāng)進(jìn)入碰撞器
2.MonoBehaviour.OnCollisionExit(Collision collision) 當(dāng)退出碰撞器
3.MonoBehaviour.OnCollisionStay(Collision collision)? 當(dāng)逗留碰撞器
collider的性能和效率大概的順序是:Sphere Collider > Capsule > Box Collider > Mesh Collider
碰撞器是另一種組件,它和剛體一起,來(lái)使碰撞發(fā)生。如果兩個(gè)剛體撞在一起,物理引擎將不會(huì)計(jì)算碰撞除非它們包含一個(gè)碰撞器組件。沒(méi)有碰撞器的剛體,會(huì)在物理模擬中相互穿透。碰撞器必須獨(dú)立于剛體加在對(duì)象上。碰撞器并不一定需要附加剛體,但是要使移動(dòng)物體具有碰撞效果必須附加剛體。為了使兩個(gè)觸發(fā)器碰撞時(shí)發(fā)出碰撞事件,其中一個(gè)必須包含剛體。
網(wǎng)格碰撞器之間通常不相互碰撞,但如果一個(gè)網(wǎng)格碰撞器被標(biāo)記為凸起的(Convex ),那么它就可以與其他網(wǎng)格碰撞器碰撞,對(duì)移動(dòng)的對(duì)象使用基本/組合碰撞器,而對(duì)靜態(tài)環(huán)境對(duì)象使用網(wǎng)格碰撞器。碰撞網(wǎng)格使用背面剔除(或譯背面揀選,指正面多邊形擋住了在它后面的背面多邊形,Direct3D將通過(guò)揀選(即刪除多余的處理過(guò)程)背面多邊形來(lái)提高效率的過(guò)程。)如果一個(gè)對(duì)象和被背面剔除的網(wǎng)格碰撞,那也不會(huì)在物理上碰撞。
Unity組件文中將碰撞體分為3個(gè)類型:
1:Static Collider 靜態(tài)碰撞器
指的是沒(méi)有附加剛體而附加了碰撞器的游戲?qū)ο蟆_@類對(duì)象會(huì)保持靜止或者很輕微的移動(dòng)。對(duì)于環(huán)境模型十分好用,當(dāng)和剛體碰撞時(shí)而不會(huì)移動(dòng)。
2:Rigidbody Collider 剛體碰撞器
指的是同時(shí)附加了剛體和碰撞器的游戲?qū)ο蟆Mㄟ^(guò)腳本的力量和碰撞完全受物理引擎的影響。可以和只包含碰撞器的游戲?qū)ο笈鲎病?huì)成為你游戲中使用物理效果的基本類型碰撞器。
3:Kinematic Rigidbody Collider 運(yùn)動(dòng)學(xué)剛體碰撞器
指的是同時(shí)包含碰撞器和剛體,并且激活I(lǐng)sKinematic的一類游戲?qū)ο螅苿?dòng)這類游戲?qū)ο螅薷乃腡ransform組件(指的是position和rotation這類屬性),而不是用力。它們很像靜態(tài)碰撞器,不過(guò)如果你想要不停地到處移動(dòng)碰撞器,它們會(huì)更好用。這類游戲?qū)ο筮€有許多其他的獨(dú)特使用情景。
運(yùn)動(dòng)學(xué)剛體碰撞器是個(gè)非常懶惰和霸道的家伙,它碰到其他碰撞器完全沒(méi)有反應(yīng)(其實(shí)還是有點(diǎn)反應(yīng),會(huì)觸發(fā)一些碰撞函數(shù)的,后面有解釋)。它不受力、重力或扭矩的影響。可以通過(guò)設(shè)置Transform 的position和rotation來(lái)準(zhǔn)確的操作它們或者讓它們動(dòng)起來(lái),但是,它們可以和其他的非運(yùn)動(dòng)學(xué)剛體互相作用。對(duì)于放在運(yùn)動(dòng)學(xué)剛體碰撞器上面的剛體,會(huì)受到運(yùn)動(dòng)學(xué)剛體施加的摩擦力。
4:Character Controllers 角色控制器
如果想制作一個(gè)類似人的角色那就使用角色控制器。這可以是第三人稱平臺(tái)游戲、第一人稱射擊游戲的主要角色或任何敵對(duì)角色。
這類控制器不遵循物理規(guī)則因此它感覺(jué)上不對(duì)勁(在Doom中,你跑到了90英里每小時(shí),然后馬上停下而且可以極快的轉(zhuǎn)身)。不過(guò),角色控制器執(zhí)行碰撞檢測(cè)以保證你的角色可以沿著墻滑動(dòng),上下臺(tái)階等等。
角色控制器不受力影響(但是重力效果還是有的)但是可以被由代碼施加的力推動(dòng)。通常,所有類似人的角色都用角色控制器來(lái)執(zhí)行。
角色控制器本身不具物理特性,因此如果想應(yīng)用真正的物理作用——在繩上搖擺,被大石頭推動(dòng)——到你的角色,必須用剛體,這會(huì)允許你把鉸鏈或力用到你的角色上。角色控制器永遠(yuǎn)沿Y軸對(duì)齊,因此,如果你的角色需要在空間中改變方向那也必須用到剛體(比如在變化的引力控制下)。但是,要意識(shí)到調(diào)整一個(gè)剛體在角色上表現(xiàn)自然是很難的,因?yàn)橛螒蚪巧陨淼姆俏锢硖匦钥傁氡憩F(xiàn)出來(lái)。另一個(gè)困難是,角色控制器可以從特定高度的臺(tái)階上平滑地滑下,而剛體不會(huì)。
控制器不會(huì)對(duì)加在它自身上的力做出反應(yīng),也不會(huì)自動(dòng)推開(kāi)其他剛體。(這里我沒(méi)有明白,因?yàn)槲覍?shí)驗(yàn)過(guò)在一個(gè)剛體內(nèi)部實(shí)例化一個(gè)控制器,剛體是會(huì)被彈開(kāi)的。如果有人懂請(qǐng)告訴我,不勝感激!)
如果想讓角色控制器推開(kāi)其他剛體或者對(duì)象,你可以在對(duì)象附加的腳本中添加OnControllerColliderHit()函數(shù),這樣對(duì)它們施加力就能夠產(chǎn)生碰撞。
也就是說(shuō),角色控制器可以使用物理效果影響其他對(duì)象,前提是你自己寫(xiě)了腳本。
而角色控制器不能通過(guò)物理效果被其他對(duì)象影響。因此,如果你想讓你的游戲角色被物理效果影響,那就最好使用剛體而不是角色控制器。
角色控制器和運(yùn)動(dòng)學(xué)剛體有點(diǎn)像,因?yàn)樗鼈兌疾皇芰Φ淖饔茫ㄟ\(yùn)動(dòng)學(xué)剛體更像是一個(gè)剛體,只是不會(huì)受到其他任何外力的影響,就像是古代的國(guó)王,雖然和普通平民一樣都是人,但是只能他欺負(fù)別人,別人無(wú)法欺負(fù)他;而角色控制器本身就不具有物理特性,不可以推開(kāi)別人(除非寫(xiě)了自己的腳本),也不會(huì)被別人影響,只是它可以執(zhí)行碰撞檢測(cè))。但是也有幾點(diǎn)不同的地方。首先,運(yùn)動(dòng)學(xué)剛體是無(wú)法通過(guò)代碼施加力的作用來(lái)推動(dòng),但是角色控制器是可以的。第二,運(yùn)動(dòng)學(xué)剛體不會(huì)受到重力的作用,而角色控制器是有重力效果的。其次,角色控制器只能沿Y軸旋轉(zhuǎn),也就是人永遠(yuǎn)都是直立狀態(tài),不會(huì)因?yàn)槭艿搅Φ淖饔镁团肯吕玻鴦傮w是可以的。第三,角色控制器可以從特定高度臺(tái)階上平滑地滑下,而剛體不會(huì)。
剛體休眠:靜止的剛體會(huì)進(jìn)入休眠。例如,當(dāng)一個(gè)正方體掉到地板上靜止后就會(huì)進(jìn)入剛體休眠.剛體休眠完全自動(dòng)發(fā)生,只要?jiǎng)傮w的速度低于sleepAngularVelocity和sleepVelocity,該剛體就會(huì)開(kāi)始休眠.其空閑一些幀后,就會(huì)被設(shè)置成休眠狀態(tài),處于休眠狀態(tài)中的物體,不會(huì)再對(duì)其進(jìn)行碰撞檢測(cè)和模擬。這會(huì)節(jié)約大量的CPU開(kāi)銷。移動(dòng)的靜態(tài)碰撞器無(wú)法喚醒它.運(yùn)動(dòng)學(xué)剛體由于會(huì)對(duì)剛體產(chǎn)生力的作用而可以喚醒休眠中的剛體.
實(shí)例:都是A物體去撞B物體
一、A(碰撞體),B(沒(méi)有碰撞體,無(wú)論有沒(méi)有剛體),沒(méi)有觸發(fā)事件。
二、A(碰撞體),B(碰撞體),沒(méi)有觸發(fā)事件。
二、A(碰撞體和剛體,開(kāi)啟IsTrigger),B(碰撞體,關(guān)閉IsTrigger),雙方都能收到觸發(fā)事件。
三、A(碰撞體和剛體,關(guān)閉IsTrigger),B(碰撞體,開(kāi)啟IsTrigger),雙方都能收到觸發(fā)事件。
四、A (碰撞體,關(guān)閉IsTrigger),B(碰撞體和剛體,開(kāi)啟IsTrigger),沒(méi)有觸發(fā)事件。
五、A (碰撞體,開(kāi)啟IsTrigger),B(碰撞體和剛體,關(guān)閉IsTrigger),沒(méi)有觸發(fā)事件。
只要A有帶有碰撞體和剛體,正在運(yùn)動(dòng),B帶有碰撞體,不管是A撞B還是B撞A,A和B至少一個(gè)開(kāi)啟了IsTrigger,都會(huì)觸發(fā)事件.
結(jié)論:產(chǎn)生觸發(fā)事件的兩個(gè)物體會(huì)相互穿越,準(zhǔn)確的說(shuō)是因?yàn)殚_(kāi)啟IsTrigger那個(gè)物體會(huì)被物理引擎鎖忽略掉,所以會(huì)產(chǎn)生兩個(gè)物體穿越的情況。兩個(gè)對(duì)象要么都收到碰撞事件,要么都收到觸發(fā)事件,不會(huì)出現(xiàn)一個(gè)收到觸發(fā)事件,一個(gè)收到碰撞事件的情況。要使用AddForce/AddTorque利用物理引擎去操作,如果直接設(shè)置坐標(biāo),2個(gè)物體產(chǎn)生碰撞,但是會(huì)穿越彼此.
關(guān)于各種Collider的效率高低排序?yàn)?/p>
sphere Collider> capsule collider> box Collider> mesh Collider
參考:http://www.ceeger.com/Manual/Physics.html? ?
https://docs.unity3d.com/Manual/PhysicsSection.html
http://www.cnblogs.com/slysky/p/4290803.html
pc:Physics.Raycast()方法中,源頭一般是攝像機(jī),方向一般是從屏幕方向射向內(nèi)部3D空間,用屏幕坐標(biāo)轉(zhuǎn)向視口坐標(biāo)Camera.main.ScreenToViewportPoint表示方向,RaycastHit hit信息,設(shè)置LayerMask.