1. 程式人生 > >unity 所有碰撞器(觸發器),碰撞條件、結果,觸發條件、結果。。。以及碰撞函式、觸發函式的呼叫。

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