unity 所有碰撞器(觸發器),碰撞條件、結果,觸發條件、結果。。。以及碰撞函數、觸發函數的調用。


要產生碰撞必須為游戲對象添加剛體(Rigidbody)和碰撞器,剛體可以讓物體在物理影響下運動。碰撞體是物理組件的一類,它要與剛體一起添加到游戲對象上才能觸發碰撞。如果兩個剛體相互撞在一起,除非兩個對象有碰撞體時物理引擎才會計算碰撞,在物理模擬中,沒有碰撞體的剛體會彼此相互穿過。

物體發生碰撞的必要條件:
  兩個物體都必須帶有碰撞器(Collider),其中一個物體還必須帶有Rigidbody剛體。
 
在unity3d中,能檢測碰撞發生的方式有兩種,一種是利用碰撞器,另一種則是利用觸發器。
 
碰撞器:一群組件,它包含了很多種類,比如:Box Collider(盒碰撞體),Mesh Collider(網格碰撞體)等,這些碰撞器應用的場合不同,但都必須加到GameObjecet身上。
觸發器,只需要在檢視面板中的碰撞器組件中勾選IsTrigger屬性選擇框。
技術分享
 
觸發信息檢測:
  1.MonoBehaviour.OnTriggerEnter(Collider collider)當進入觸發器
  2.MonoBehaviour.OnTriggerExit(Collider collider)當退出觸發器
  3.MonoBehaviour.OnTriggerStay(Collider collider)當逗留觸發器
 
碰撞信息檢測:
  1.MonoBehaviour.OnCollisionEnter(Collision collision) 當進入碰撞器
  2.MonoBehaviour.OnCollisionExit(Collision collision) 當退出碰撞器
  3.MonoBehaviour.OnCollisionStay(Collision collision)  當逗留碰撞器
 
  兩個物體相接觸時到底執行OnTriggerEnter還是執行OnCollisionEnter方法,這兩個又有什么區別呢?
  為了驗證碰撞器與觸發器的區別,現設計一個簡單的游戲,讓小汽車與小球發生碰撞。新建一個C#腳本文件,把它拖給小汽車對象,雙擊該腳本文件進入腳本編輯器,在該腳本中加入如下兩個方法,並分別設置一個斷點:
技術分享
void OnTriggerEnter(Collider collider)
{
     //進入觸發器執行的代碼
}
void OnCollisionEnter(Collision collision) 
{
     //進入碰撞器執行的代碼
}
技術分享
  
  當未勾選碰撞器的Is Trigger選項時汽車與球體發生碰撞,進入方法OnCollisionEnter,碰撞之后汽車產生被球體撞飛的效果:
 
技術分享
技術分享
 
  如果將碰撞器的Is Trigger屬性選中,再次啟動游戲讓球體與汽車產生接觸,這時進入方法OnTriggerEnter。之后球體直接穿過汽車,但球體與汽車都沒有產生碰撞效果:
 
技術分享
技術分享
 
unity3d中的碰撞器和觸發器的區別?
 
  碰撞器是觸發器的載體,而觸發器只是碰撞器身上的一個屬性
  當Is Trigger=false時,碰撞器根據物理引擎引發碰撞,產生碰撞的效果,可以調用OnCollisionEnter/Stay/Exit函數;
  當Is Trigger=true時,碰撞器被物理引擎所忽略,沒有碰撞效果,可以調用OnTriggerEnter/Stay/Exit函數。
 
  如果既要檢測到物體的接觸又不想讓碰撞檢測影響物體移動或要檢測一個物件是否經過空間中的某個區域這時就可以用到觸發器
 
例子:
  碰撞器:汽車被撞飛、皮球掉在地上又彈起效果
  觸發器:人站在靠近門的位置門自動打開效果
 
另外,collider的性能和效率大概的順序是:Sphere Collider > Capsule > Box Collider > Mesh Collider.
 

  碰撞器是另一種組件,它和剛體一起,來使碰撞發生。如果兩個剛體撞在一起,物理引擎將不會計算碰撞除非它們包含一個碰撞器組件。沒有碰撞器的剛體,會在物理模擬中相互穿透。碰撞器必須獨立於剛體加在對象上。碰撞器並不一定需要附加剛體,但是要使移動物體具有碰撞效果必須附加剛體。為了使兩個觸發器碰撞時發出碰撞事件,其中一個必須包含剛體。

技術分享
通過菜單Component->Physics menu來添加一個碰撞器。

Box Collider盒碰撞器--基本形狀是個盒子。

Sphere Collider 球碰撞器--基本形狀是個球。

Capsule Collider 膠囊碰撞器--基本形狀是個膠囊。

Mesh Collider 網格碰撞器--從物體的網格創建一個碰撞器。不能與其他網格碰撞器相碰撞。

Wheel Collider 輪碰撞器--特殊的碰撞器,用於創建車或其他移動交通工具。

碰撞器屬性:

Material 材質

Is Trigger 是否觸發器

Radius 半徑

Center 中心

Size 大小 在X、Y、Z三維上的碰撞器尺寸。

Mesh 網格

Smooth Sphere Collisions 平滑性狀碰撞 當被激活,碰撞網格法線是平滑的。用於平滑表面比如由沒有棱角的平滑起伏組成的起伏地表時應該激活。

Convex 凸起的 如激活,該網格碰撞器將會和其他網格碰撞器碰撞。凸起的網格碰撞器限制在255個三角形面內。

膠囊碰撞器的半徑和高度都可以單獨調節。用於置於其兩極間的角色控制器,或者和其他碰撞器結合用於不規則的形狀。

技術分享

 

當你有一個復雜網格卻不適用網格碰撞器的情況下,使用組合碰撞器是個好的選擇。要創建組合碰撞器,先為你的碰撞物體創建子對象,然后對每個子對象創建一個基本碰撞器。這樣就允許你輕易的獨立移動、旋轉和放縮每個碰撞器。

網格碰撞器之間通常不相互碰撞,但如果一個網格碰撞器被標記為凸起的(Convex ),那么它就可以與其他網格碰撞器碰撞。典型的解決方案是,對移動的對象使用基本碰撞器,而對靜態環境對象使用網格碰撞器。

碰撞網格使用背面剔除(或譯背面揀選,指正面多邊形擋住了在它后面的背面多邊形,Direct3D將通過揀選(即刪除多余的處理過程)背面多邊形來提高效率的過程。)如果一個對象和被背面剔除的網格碰撞,那也不會在物理上碰撞。

Static Colliders 靜態碰撞器

一個靜態碰撞器是一個包含碰撞器但不含剛體的游戲對象。靜態碰撞器用於總是待在同一個地方不移動的水平幾何體。你能把一個網格碰撞器添加到已存在的圖形網格(甚至比用輸入設置產生碰撞器復選框好用),或者你可以使用了另一種碰撞器類型。

你不要逐幀移動 一個靜態碰撞器,移動靜態碰撞器將導致PhysX引擎的內部重置,非常耗費資源,而且會造成性能的極大下降。另外,基於一個靜態碰撞器喚醒其他剛體的行為 是未定義的,而且移動靜態碰撞器將不會對碰到它的剛體施加摩擦力。取而代之的是,要移動的碰撞器要保持是運動學剛體。

  Layer-Based Collision Detection 基於層的碰撞檢測

在Unity3以后版本,我們介紹了一種稱為“基於層的碰撞檢測”(Layer-Based Collision Detection)的東西,可以讓你有選擇地控制Unity對象和他們附加的特定層碰撞。

選擇選定游戲對象的層.

技術分享

 

Edit->Project Settings->Physics.,打開物理引用界面. 在碰撞矩陣中選擇要與其他層相互作用的層,勾選即可.

技術分享

 

另外,看下有人做的物理碰撞實驗:【Unity】物理碰撞實驗

文中提到Unity組件文中將碰撞體分為3個類型:

Static Collider 靜態碰撞器

These are GameObjects that do not have a Rigidbody attached, but do have a Collider attached. These objects should remain still, or move very little. These work great for your environment geometry. They will not move if a Rigidbody collides with them.

指的是沒有附加剛體而附加了碰撞器的游戲對象。這類對象會保持靜止或者很輕微的移動。對於環境模型十分好用,當和剛體碰撞時而不會移動。 

Rigidbody Collider 剛體碰撞器 

These GameObjects contain both a Rigidbody and a Collider. They are completely affected by the physics engine through scripted forces and collisions. They might collide with a GameObject that only contains a Collider. These will likely be your primary type of Collider in games that use physics.

指的是同時附加了剛體和碰撞器的游戲對象。通過腳本的力量和碰撞完全受物理引擎的影響。可以和只包含碰撞器的游戲對象碰撞。將會成為你游戲中使用物理效果的基本類型碰撞器。 

Kinematic Rigidbody Collider 運動學剛體碰撞器

This GameObject contains a Collider and a Rigidbody which is marked IsKinematic. To move this GameObject, you modify its Transform Component, rather than applying forces. They‘re similar to Static Colliders but will work better when you want to move the Collider around frequently. There are some other specialized scenarios for using this GameObject.

指的是同時包含碰撞器和剛體,並且激活IsKinematic的一類游戲對象,要移動這類游戲對象,要修改它的Transform組件(指的是position和rotation這類屬性),而不是用力。它們很像靜態碰撞器,不過如果你想要不停地到處移動碰撞器,它們會更好用。這類游戲對象還有許多其他的獨特使用情景。

運動學剛體碰撞器是個非常懶惰和霸道的家伙,它碰到其他碰撞器完全沒有反應(其實還是有點反應,會觸發一些碰撞函數的,后面有解釋)。它不受力、重力或扭矩的影響。可以通過設置Transform 的position和rotation來准確的操作它們或者讓它們動起來,但是,它們可以和其他的非運動學剛體互相作用。對於放在運動學剛體碰撞器上面的剛體,會受到運動學剛體施加的摩擦力。

 

還有一類叫做角色控制器。

Character Controllers 角色控制器

You use Character Controllers if you want to make a humanoid character. This could be the main character in a third person platformer, FPS shooter or any enemy characters.

如果想制作一個類似人的角色那就使用角色控制器。這可以是第三人稱平台游戲、第一人稱射擊游戲的主要角色或任何敵對角色。

These Controllers don‘t follow the rules of physics since it will not feel right (in Doom you run 90 miles per hour, come to halt in one frame and turn on a dime). Instead, a Character Controller performs collision detection to make sure your characters can slide along walls, walk up and down stairs, etc.

這類控制器不遵循物理規則因此它感覺上不對勁(在Doom中,你跑到了90英里每小時,然后馬上停下而且可以極快的轉身)。不過,角色控制器執行碰撞檢測以保證你的角色可以沿着牆滑動,上下台階等等。

Character Controllers are not affected by forces but they can push Rigidbodies by applying forces to them from a script. Usually, all humanoid characters are implemented using Character Controllers.

角色控制器不受力影響(但是重力效果還是有的)但是可以被由代碼施加的力推動。通常,所有類似人的角色都用角色控制器來執行。

Character Controllers are inherently unphysical, thus if you want to apply real physics - Swing on ropes, get pushed by big rocks - to your character you have to use a Rigidbody, this will let you use joints and forces on your character. Character Controllers are always aligned along the Y axis, so you also need to use a Rigidbody if your character needs to be able to change orientation in space (for example under a changing gravity). However, be aware that tuning a Rigidbody to feel right for a character is hard due to the unphysical way in which game characters are expected to behave. Another difference is that Character Controllers can slide smoothly over steps of a specified height, while Rigidbodies will not.

角色控制器本身不具物理特性,因此如果想應用真正的物理作用——在繩上搖擺,被大石頭推動——到你的角色,必須用剛體,這會允許你把鉸鏈或力用到你的角色上。角色控制器永遠沿Y軸對齊,因此,如果你的角色需要在空間中改變方向那也必須用到剛體(比如在變化的引力控制下)。但是,要意識到調整一個剛體在角色上表現自然是很難的,因為游戲角色自身的非物理特性總想表現出來。另一個困難是,角色控制器可以從特定高度的台階上平滑地滑下,而剛體不會。

 

The Controller does not react to forces on its own and it does not automatically push Rigidbodies away.

控制器不會對加在它自身上的力做出反應,也不會自動推開其他剛體。(這里我沒有明白,因為我實驗過在一個剛體內部實例化一個控制器,剛體是會被彈開的。如果有人懂請告訴我,不勝感激!)

If you want to push Rigidbodies or objects with the Character Controller, you can apply forces to any object that it collides with via the OnControllerColliderHit() function through scripting.

如果想讓角色控制器推開其他剛體或者對象,你可以在對象附加的腳本中添加OnControllerColliderHit()函數,這樣對它們施加力就能夠產生碰撞。

也就是說,角色控制器可以使用物理效果影響其他對象,前提是你自己寫了腳本。

On the other hand, if you want your player character to be affected by physics then you might be better off using a Rigidbody instead of the Character Controller.

而角色控制器不能通過物理效果被其他對象影響。因此,如果你想讓你的游戲角色被物理效果影響,那就最好使用剛體而不是角色控制器。

 

角色控制器和運動學剛體有點像,因為它們都不受力的作用(運動學剛體更像是一個剛體,只是不會受到其他任何外力的影響,就像是古代的國王,雖然和普通平民一樣都是人,但是只能他欺負別人,別人無法欺負他;而角色控制器本身就不具有物理特性,不可以推開別人(除非寫了自己的腳本),也不會被別人影響,只是它可以執行碰撞檢測)。但是也有幾點不同的地方。首先,運動學剛體是無法通過代碼施加力的作用來推動,但是角色控制器是可以的。第二,運動學剛體不會受到重力的作用,而角色控制器是有重力效果的。其次,角色控制器只能沿Y軸旋轉,也就是人永遠都是直立狀態,不會因為受到力的作用就趴下啦,而剛體是可以的。第三,角色控制器可以從特定高度台階上平滑地滑下,而剛體不會。

說了這么多,暈了吧,恩,我也暈了。所以我們來做下實驗!我們通過一個最簡單的場景,即一個平行光、一個平面、兩個正方體來試驗一下。通過給兩個正方體添加不同的碰撞體類型來觀察是否會發生碰撞。

技術分享

下面的實驗中,一個正方體保持靜止,另一個正方體我們通過代碼來控制運動,即上下左右方向鍵可以控制它的上下左右運動。

 

 

移動的靜態碰撞器VS靜止的靜態碰撞器

沒有任何碰撞效果。這在意料之中,因為沒有一個添加了Rigdbody屬性,肯定不會碰撞啦!
 
 

移動的靜態碰撞器VS靜止的剛體碰撞器

沒有任何碰撞效果。
這個結果有點意外,明明一個已經添加了Rigdbody,為什么還是無法發生碰撞呢?這是因為添加了Rigdbody的正方體是靜止的,而靜止的剛體會進入休眠。好吧,又遇到了新的名詞,  剛體休眠。例如,當一個正方體掉到地板上靜止后就會進入剛體休眠。剛體休眠完全自動發生。只要剛體的速度低於sleepAngularVelocity和sleepVelocity,該剛體就會開始休眠。其空閑一些幀后,就會被設置成休眠狀態。處於休眠狀態中的物體,不會再對其進行碰撞檢測和模擬。這會節約大量的CPU開銷。這就解釋了為什么我們這個實驗里沒有碰撞發生,因為它睡覺去了,而那個移動的靜態碰撞器又無法喚醒它,所以它壓根就不知道有人碰到了自己。這里又有一個問題了,那么什么情況下可以喚醒已經休眠了的剛體呢?有4中情況:
  • 被施加了外力,也就是說在代碼里使用了AddForce;
  • 剛體的屬性發生了變化;
  • 和它通過關節連接的剛體發生了移動,因為連帶關系,所以它也被喚醒了;
  • 被其他剛體碰撞器碰撞。但是,只有處於運動狀態中的剛體(包括普通的剛體碰撞器和運動學剛體碰撞器)能喚醒休眠中的剛體,靜態碰撞器不能喚醒休眠中的剛體。即如果你將一個靜態碰撞器(沒有和任何剛體綁定過)綁定到處於休眠中的剛體,或者將靜態碰撞器抽離處於休眠中的剛體時,這個休眠中的剛體是不會被喚醒的。但是如果你將一個運動中的剛體從它所屬的且處於休眠狀態中的頂層剛體移出時,處於休眠中的剛體將會被喚醒,且會在圖形更新里被重新正確的計算。
最后這句話時什么意思呢?我們再做兩個實驗好了。還是兩個正方體,我們將一個正方體放在另一個的上方。
技術分享 
在兩個實驗里,上方的正方體都是普通的剛體碰撞器,而下方的正方體有所不同,我們可以通過代碼移動下方的正方體使得它從上方正方體的下面移開。
第一個實驗里,下方的正方體是一個靜態碰撞器。當我們移開后,上方的正方體直直地下落,直到碰到地板,期間沒有任何物理效果(除了重力效果)。
第二個實驗里,下方的正方體是一個運動學剛體碰撞器。當我們移開下方正方體的過程中,我們會發現上方的正方體會受到摩擦力的左右而也發生了一定移動,當兩個正方體完全分離后,上方的正方體晃動着掉到了地板上(因為之前受到了摩擦力)。
好了,有點明白了嗎?靜態碰撞器是不會喚醒休眠剛體的(第一個實驗),而運動學剛體由於會對剛體產生力的作用而可以喚醒休眠中的剛體。
 
再提一個問題,如果上面的正方體是運動學剛體碰撞器呢?那么無論下面是什么碰撞器它都沒有反應,因為它是國王啦,不受到任何外力的影響,包括重力!
 
 

移動的剛體碰撞器VS靜止的靜態碰撞器

有碰撞效果,具體為:對於移動的剛體碰撞器在遇到靜態碰撞器后會產生物理效果,如反彈、無法前進等;對於靜止的靜態碰撞器,會產生輕微的碰撞效果,如輕微的晃動,但是不會移動。
 
 

移動的剛體碰撞器VS靜止的剛體碰撞器

有碰撞效果,對於兩個物體都出現正常的物理效果,如反彈等。
 
 

移動的靜態碰撞器VS靜止的運動學剛體碰撞器

沒有任何碰撞效果。運動學剛體碰撞器是不受到任何外力作用的。
 
 

移動的運動學剛體碰撞器VS靜止的靜態碰撞器

沒有任何碰撞效果。運動學剛體碰撞器是不受到任何外力作用的。
 
 

移動的運動學剛體碰撞器VS靜止的剛體碰撞器

有碰撞效果,但僅剛體碰撞器有碰撞效果,如反彈等,運動學剛體碰撞器不受力的作用。
 
 

移動的剛體碰撞器VS靜止的運動學剛體碰撞器

有碰撞效果,但僅剛體碰撞器有碰撞效果,如反彈等,運動學剛體碰撞器就像一堵牆一樣一動不動。
 
 

移動的運動學剛體碰撞器VS靜止的運動學剛體碰撞器

兩個太上皇相見了會怎么樣呢?沒有任何反應……就像兩個靜態碰撞器一樣。
 
 
 
下面,將一個正方體換成角色控制器,繼續實驗。
技術分享 
 
 

移動的靜態碰撞器VS靜止的角色控制器

沒有任何碰撞效果。
 
 

移動的剛體碰撞器VS靜止的角色控制器

有碰撞效果,剛體碰撞器遇到角色控制器后會發生反彈,無法繼續前進,而角色控制器沒有任何效果。
 
 

移動的運動學剛體碰撞器VS靜止的角色控制器

沒有任何碰撞效果,會互相穿過。
 
 

移動的角色控制器VS靜止的靜態碰撞器

沒有任何碰撞效果,會互相穿過。 
 
 

移動的角色控制器VS靜止的剛體碰撞器

有碰撞效果,剛體碰撞器被彈開。
 
 

移動的角色控制器VS靜止的運動學剛體碰撞器

沒有任何碰撞效果,會互相穿過。 
 
 
 

碰撞信息和觸發信息

 
對於碰撞時是否會發出碰撞函數(或觸發信息),可以見下表。碰撞信息是指OnCollisionEnter() OnCollisionStay()和 OnCollisionExit()這三個函數,而觸發信息指的是OnTriggerEnter() OnTriggerStay和OnTriggerExit()三個函數。
 
 
Collision detection occurs and messages are sent upon collision
碰撞后有碰撞檢測並有碰撞信息發出
  Static Collider
靜態碰撞器
Rigidbody Collider
剛體碰撞器
Kinematic 
Rigidbody Collider
運動學剛體碰撞器
Static 
Trigger Collider
靜態觸發碰撞器
Rigidbody 
Trigger Collider
剛體觸發碰撞器
Kinematic Rigidbody 
Trigger Collider
運動學剛體觸發碰撞器
Static Collider 靜態碰撞器   Y        
Rigidbody Collider 剛體碰撞器 Y Y Y      
Kinematic Rigidbody Collider 
運動學剛體碰撞器
  Y        
Static Trigger Collider
靜態觸發碰撞器
           
Rigidbody Trigger Collider
剛體觸發碰撞器
           
Kinematic Rigidbody Trigger Collider
運動學剛體觸發碰撞器
           
Trigger messages are sent upon collision
碰撞后有觸發信息
  Static Collider
靜態碰撞器
Rigidbody Collider
剛體碰撞器
Kinematic 
Rigidbody Collider
運動學剛體碰撞器
Static 
Trigger Collider
靜態觸發碰撞器
Rigidbody 
Trigger Collider
剛體觸發碰撞器
Kinematic Rigidbody 
Trigger Collider
運動學剛體觸發碰撞器
Static Collider 靜態碰撞器         Y Y
Rigidbody Collider 剛體碰撞器       Y Y Y
Kinematic Rigidbody Collider
運動學剛體碰撞器
      Y Y Y
Static Trigger Collider 靜態觸發碰撞器   Y Y   Y Y
Rigidbody Trigger Collider
剛體觸發碰撞器
Y Y Y Y Y Y
Kinematic Rigidbody Trigger Collider
運動學剛體觸發碰撞器
Y Y Y Y Y Y


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM