茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671280 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_60D_00015.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

Game Play Maker : [轉貼]簡單瞭解 Unity 「Collision碰撞」與「Trigger觸發」

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]簡單瞭解 Unity 「Collision碰撞」與「Trigger觸發」

[Unity] 簡單瞭解「Collision碰撞」與「Trigger觸發」

作者:旭曜靈│2014-01-06 17:58:01│贊助:6│人氣:2066
Unity 是套非常好用的遊戲開發引擎,並且有提供 免費版本 給一般使用者,
內建的物理系統讓使用者不需寫長長的程式碼,
就能夠迅速設定好所有物件之間的碰撞關係,
做出讓角色走不過去的牆、或是可以射穿牆壁的子彈等等。

不過它的設定相當細,若是分不清其中差異,很容易就會陷入鬼打牆的窘境。

幸好這是個資訊發達的時代,網路上總有熱心人士分享資訊──


光看表格可能不夠直覺,也無法瞭解物件動靜的影響,
所以我以自己的實測心得解釋一下。

主要觀念──

1) 想要讓程式判斷兩個物件有接觸,則雙方都必需要有Collider(碰撞器),
 並且“正在動的一方”一定要有Rigidbody(剛體)才有效,另一方有沒有剛體無所謂。
 ※也就是說,如果動的一方沒有剛體,它去撞的靜止一方即使有剛體,也是當作沒撞到。


2) 接下來有兩種方式判斷接觸,
  一、 Collision碰撞,造成物理碰撞,可以在碰撞時執行OnCollision事件。
  二、 Trigger觸發,取消所有物理碰撞,可以在觸發時執行OnTrigger事件。
 所以兩個物件A跟B接觸時,不可能同時產生碰撞+觸發,最多產生其中一種,
 但是可以辦到讓A跟B產生碰撞,A跟C產生觸發。

3) 產生接觸的設定方式如下──


 一、Collision碰撞:雙方都有碰撞器,並且至少動的一方有剛體,
   就會造成碰撞,可以執行OnCollision事件。
   ※但若雙方都勾了Kinematic運動學,或任一方勾了Trigger觸發器,則碰撞無效。

 二、Trigger觸發:雙方都有碰撞器,並且至少動的一方有剛體,
   並且至少其中一方的碰撞器有勾觸發器,就會造成觸發,可以執行OnTrigger事件。


4) 接觸後的事件又細分為Enter、Stay、Exit三種,
 以Trigger為例,就是OnTriggerEnter、OnTriggerStay、OnTriggerExit(Collision依此類推)。
 Enter事件表示當兩個物件接觸的瞬間,會執行一次這個事件;
 Stay事件表示當兩個物件持續接觸時,會不斷執行這個事件;
 Exit事件表示當兩個物件分開的瞬間,會執行一次這個事件。




細部解釋──

【Collider碰撞器】:最重要的核心!會對其他物件產生碰撞。
 若自身要受到碰撞的話,則需要碰撞器+剛體,缺一不可。
 若自身要受到程式Translate位移或Rotate旋轉,也至少需要碰撞器。

【IsTrigger觸發器】勾了就不允許自身受到/造成碰撞,
 也不會受到重力等物理作用力影響。
 雙方會直接穿越,就只能判斷觸發。
 但自身還是可以受到程式位移或旋轉。

【Rigidbody剛體】:允許自身受到碰撞,允許雙方產生Trigger觸發。
 加了剛體的物件才會受到物理作用力,如受到重力而落下、被物理作用力推動/旋轉,
 也無法主動穿越其他碰撞器,這都是受到剛體的影響。
 而對方若是沒加剛體,對方就不會受到碰撞的作用力推擠,
 但仍然可以判斷雙方有碰撞。


 打個比方,沒加剛體的碰撞器就像鬼魂,加了之後就像一輛車,
 鬼不怕撞車而穿過去,但車還是會知道自己撞到鬼而停下來。

【IsKinematic運動學】:不允許自身受到碰撞,但還是會對其他物件造成碰撞。
 也不會受到重力等物理作用力影響。
 ※雙方都勾運動學的話,雙方都不會受到碰撞,會直接穿越,
  因此會被視為沒有碰撞到,無法執行OnCollision事件。
 ※雖然自身碰撞器不加剛體也可以達到這效果,但有可能會導致雙方都沒剛體,

  而無法產生任何碰撞、觸發,所以會動的物件還是都加剛體然後都勾運動學較好。

【Constraints限制】:
 自身受到碰撞時, 勾選的位置(Position)、角度(Rotarion)不受力。
 很類似把運動學拆成六個細項來設定,但唯一差別在於仍然算有碰撞
 可以照常執行OnCollision事件。

【Drag空氣阻力】:提高數值可減少落下速度、被撞飛距離。



以上就是比較常用到的重要概念,只要照著實際操作一次就很容易明白了。

另外由於今天分享的是程式技術,
所以這個月預計還是會再寫一篇跟企劃有關的文章,請大家多多支持鼓勵唷!

原文出處:[Unity] 簡單瞭解「Collision碰撞」與「Trigger觸發」 - YawLing的創作 - 巴哈姆特
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]unity3d 理解剛體(Rigidbody)和碰撞體(Collider)以及觸發器(Is Trigger)

剛體(Rigidbody)的官方 (摘自Unity3d的官方指導書《Unity4.x從入門到精通》) 解釋如下:

Rigidbody(剛體)組件可使遊戲對像在物理系統的控制下來運動,剛體可接受外力與扭矩力用來保證遊戲對像像在真實世界中那樣進行運動。任何遊戲對像只有添加了剛體組件才能受到重力的影響,通過腳本為遊戲對像添加的作用力以及通過NVIDIA物理引擎與其他的遊戲對像發生互動的運算都需要遊戲對像添加了剛體組件。

個人理解就是剛體是用來模擬物體受到一個力作用時候的表現, 這個從剛體中的參數就可以看出:


全是關於物體受到力之後,怎麼運動的參數,比如Mass質量,Drag阻力。

碰撞體的官方(摘自Unity3d的官方指導書《Unity4.x從入門到精通》)解釋如下:


碰撞體是物理組件的一類,它要與剛體一起添加到遊戲對像上才能觸發碰撞。如果兩個剛體相互撞在一起,除非兩個對像有碰撞體時物理引擎才會計算碰撞,在物理模擬中,沒有碰撞體的剛體會彼此相互穿過。

個人是這樣理解的,為什麼要判斷碰撞,判斷碰撞就是需要計算力,無論是阻力也好,動力也好,如果此時物體有剛體組件,那麼物體就會在力的作用下運動。如果這個物體沒有剛體,那麼碰撞產生的力就沒有任何意義了,那計算碰撞也就沒有任何意義了。

所以,我們可以推斷出,如果兩個碰撞體都沒有剛體組件,那麼這兩個物體即使相互發生了碰撞,那麼也不會有碰撞事件的。

官網上的碰撞的圖如下(註:據說是官網的圖,我在網上很多地方看到了,但我目前為止還沒找到在官網的哪個位置哈):


從上面的圖中我們看出來碰撞的雙方中一定要有一個Rigidbody存在,並且碰撞雙方必須都要有碰撞體組件。

但做實驗的時候發現了一個很詭異的事情, 就是 發生碰撞的主體一定是要帶剛體的,即只有帶剛體的碰撞體去撞其他碰撞體時,雙方才會收到碰撞事件,以下是我做的實驗:

一、控制A(剛體加碰撞體)撞擊 靜止的B(只有碰撞體),雙方能收到碰撞事件。

二、控制B(只有碰撞體)撞擊 靜止的A(剛體加碰撞體),雙方收不到碰撞事件。

三、讓A(剛體加碰撞體)自由下落,然後控制B(只有碰撞體)去撞擊A,雙方能受到碰撞事件。

得出的結論似乎是如果碰撞雙方只有一個有剛體,那麼那個剛體一定要處於運動的狀態下才會有碰撞事件發生。

接下來就是IsTrigger選項了,上面的情況都沒有觸發訊息,先列舉一下觸發事件和碰撞事件,如下:

觸發訊息檢測:
1.MonoBehaviour.OnTriggerEnter( Collider other )當進入觸發器
2.MonoBehaviour.OnTriggerExit( Collider other )當退出觸發器
3.MonoBehaviour.OnTriggerStay( Collider other )當逗留觸發器
碰撞訊息檢測:
1.MonoBehaviour.OnCollisionEnter( Collision collisionInfo ) 當進入碰撞器
2.MonoBehaviour.OnCollisionExit( Collision collisionInfo ) 當退出碰撞器
3.MonoBehaviour.OnCollisionStay( Collision collisionInfo )  當逗留碰撞器


下面是一張關於觸發的關係圖,如下(註:同樣是來自網上,我目前還沒在官網上找著哈)



下面就是我做的測試情況,都是A物體去撞B物體。

一、A( 碰撞體),B(沒有碰撞體,無論有沒有剛體),沒有觸發事件。

二、A(碰撞體),B(碰撞體),沒有觸發事件。

二、A(碰撞體和剛體,開啟IsTrigger),B(碰撞體,關閉 IsTrigger),雙方都能收到觸發事件。

三、A(碰撞體和剛體,關閉 IsTrigger),B(碰撞體,開啟 IsTrigger),雙方都能收到觸發事件。

四、A ( 碰撞體,關閉 IsTrigger),B( 碰撞體和剛體,開啟 IsTrigger),沒有觸發事件。

五、A ( 碰撞體,開啟 IsTrigger ),B( 碰撞體和剛體,關閉 IsTrigger),沒有觸發事件。

額外實驗:

六、A( 碰撞體和剛體,開啟IsTrigger)自由下落,B(碰撞體)撞擊A,雙方都能收到觸發事件。

根據上面的實驗得出,如果要收到觸發事件,必須滿足如下三個條件:

1、必須都要有碰撞器組件(Collider),其實上面的碰撞事件同樣也需要這個前提條件。

2、必須有一個物體帶剛體組件,並且處於運動狀體中(包括主動運動去撞擊別人和在運動過程中被別人撞擊)。

3、兩個碰撞器中至少有一個開啟了IsTrigger。

此外還有兩點:

一、產生觸發事件的兩個物體會相互穿越,準確的說是因為開啟IsTrigger那個物體會被物理引擎鎖忽略掉,所以會產生兩個物體穿越的情況。

二、兩個對像要麼都收到碰撞事件,要麼都收到觸發事件,不會出現一個收到觸發事件,一個收到碰撞事件的情況。


還有一個經驗點就是,在控制一個物體A去撞另一個物體B時,不要直接去修改物體A的Transform的position屬性,因為你會發現如果即使兩者發生了碰撞也還是會穿越的,原因就在於我們是直接設置的坐標,如果物體A有剛體組件的話,應該用AddForce,給物體添加一個力,然後讓物理引擎去讓物體動,此時如果發生了碰撞的話,就不會穿越了。

好吧,下午折騰了半天之後,我就一直在想那個IsTrigger有啥用,後來在網上搜了一下,說是可以做門的自動打開,就讓我想起了Unity3d 4自帶的哪個AngryBots例子,貌似當控制主角走到一個門前時,那個門會自動打開。

於是就打開那個例子工程,去看,發現果然是這樣的,大概原理就是在門前面放了一個設置了IsTrigger的透明碰撞體,用於專門監聽碰撞,當主角進入這個區域時,就通過 OnTriggerEnter事件把門預先打開。

如圖:



原文出處: unity3d 理解刚体(Rigidbody)和碰撞体(Collider)以及触发器(Is Trigger),边学边更新 - monzart的专栏 - 博客频道 - CSDN.NET
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Unity3d碰撞檢測中碰撞器與觸發器的區別

Unity3d碰撞檢測中碰撞器與觸發器的區別

要產生碰撞必須為遊戲對像添加剛體(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#腳本文件,把它拖給小汽車對象,雙擊該腳本文件進入腳本編輯器,在該腳本中加入如下兩個方法,並分別設置一個斷點:

 OnTriggerEnter(Collider collider)
{
進入觸發器執行的代碼
}
OnCollisionEnter(Collision collision)
{
進入碰撞器執行的代碼
}

當未勾選碰撞器的Is Trigger選項時汽車與球體發生碰撞,進入方法OnCollisionEnter,碰撞之後汽車產生被球體撞飛的效果:
如果將碰撞器的Is Trigger屬性選中,再次啟動遊戲讓球體與汽車產生接觸,這時進入方法OnTriggerEnter。之後球體直接穿過汽車,但球體與汽車都沒有產生碰撞效果:
unity3d中的碰撞器和觸發器的區別?
 
碰撞器是觸發器的載體,而觸發器只是碰撞器身上的一個屬性
當Is Trigger=false時,碰撞器根據物理引擎引發碰撞,產生碰撞的效果,可以調用OnCollisionEnter/Stay/Exit函數;
當Is Trigger=true時,碰撞器被物理引擎所忽略,沒有碰撞效果,可以調用OnTriggerEnter/Stay/Exit函數。
 
如果既要檢測到物體的接觸又不想讓碰撞檢測影響物體移動或要檢測一個物件是否經過空間中的某個區域這時就可以用到觸發器
 
例子:
碰撞器:汽車被撞飛、皮球掉在地上又彈起效果
觸發器:人站在靠近門的位置門自動打開效果


原文出處:Unity3d碰撞检测中碰撞器与触发器的区别 - Infly - 博客园
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Unity3D 碰撞檢測及 Trigger 觸發器的使用及注意事項

Unity3D碰撞檢測及Trigger觸發器的使用及注意事項

首先新建一個Cube,其本身就已自帶了碰撞器Collider,如圖

要使用Trigger檢測物體進入,則需要勾選Is Trigger選項
碰撞檢測觸發器Trigger 有別於碰撞檢測器 Collision,其可以不受物理效果影響,一些可穿透區域的碰撞檢測,可以使用Trigger來進行碰撞檢測
常用方法如下:
OnTriggerEnter 進入時
OnTriggerExit 離開時
OnTriggerStay 處於時

同上碰撞檢測器 Collision 也有3個方法:
OnCollisionEnter
OnCollisionExit
OnCollisionStay

這裡我們需要為跑道添加一個終點撞線的機制,所以使用可穿透的碰撞檢測觸發器Trigger

代碼如下:

1
2
3
4
5
    void OnTriggerEnter (Collider collider )
    {
        print
(collider . gameObject . name + ":" + Time . time ) ;
     
    }

OnTriggerEnter傳入的參數必須為Collider,故能觸發該函數的對象必須具有Collider組建。這裡我們用的是角色控制器Character Controller 自帶了Collider組建
此時每當有角色撞線時即會列印角色名及系統時間

接下來我們使用碰撞檢測器 Collision 來進行一個碰撞檢測
首先取消被撞擊對像上的Is Trigger選項,並添加腳本代碼如下

1
2
3
4
5
    void OnCollisionEnter (Collision collision )

    {
        print (collision . gameObject . name + ":" + Time . time ) ;
     
    }

此時用例為兩個cube,需要注意的是,撞擊者cube均要添加剛體組件,否則無效,Trigger同理。
同時cube的長寬高,不能為0,否則無法觸發。
另一問題是角色控制器的膠囊體與Cube Collider碰撞不激活碰撞檢測,但是手動往前推動一下就會觸發,該問題目前尚未解決,有知道的朋友歡迎留言討論。

本篇疑問尚且留存,待解決後更正。

BeiTown
2013.03.09


原文出處:BeiTown's Coder 编码之源 » Unity3D碰撞检测及Trigger触发器的使用及注意事项
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Unity3D 中實現簡單的碰撞檢測

[Unity3D]在Unity3D中實現簡單的碰撞檢測

需求:當立方體Cube碰到地面Plane的時候,輸出碰撞物體的名稱,則表述檢測到立方體碰撞了地面。

過程:

1.搭建一個簡單的場景。

在新的工程中選擇File->new Scene創建新的場景。

然後在該場景中添加地板: GameObject->Create Other->Plain,

以及正方體:GameObject->Create Other->Cube。

給正方體添加剛體:Component->Physics->Rigidbody。


添加後可以設置剛體屬性。

在Project處右擊,選擇Import Package->Physic Matarials。

引入完成後可以直接把材質拖動到Hierachy窗口的組件中。

bouncy:彈力十足的蹦蹦跳跳型。

ice:像冰塊一樣碰撞。

metal:像金屬一樣碰撞。

rubber:像橡膠一樣碰撞。

wood:像木頭一樣碰撞。

然後在「Hierarchie」面板中單擊表示地板的組件,然後在Inspector中給它命名為「 Ground

然後調整他們的位置大約像這樣:




2.創建腳本文件添加監聽。


選擇Assets->Create->Javascript,創建JS文件並且重命名為 「Collision」

在Project窗口中雙擊它,Unity會啟動Monodevelop來編輯js文件。
清除裡面默認創建的代碼。寫上。


function OnCollisionEnter(obj:Collision)
{
Debug.Log("Collider:"+obj.collider.name+" gameObject:"+obj.gameObject.name);
}



onCollisionEnter函數解釋:這個函數是在被綁定的物體與其他物體發生碰撞的時候被調用。

obj參數解釋:被撞的物體參數,類型是Collision,在本例中就是「Ground」。

攜帶變量gameObject,是我們碰撞的物體。

3、將腳本文件拖到立方體上實現綁定

在"Project"面板中選中collision.js腳本,按住鼠標左鍵不放,直接拖入「Hierarchie」面板中,放到Ground上,鬆開鼠標即完成綁定。可以在右邊的Inspetor面板查看相關內容。


現在可以運行該程式了。

運行後在界面左下角會輸出:

        Collider:Cube gameObject:Cube

至此一個簡單的碰撞檢測便完成了。


原文出處: [Unity3D]在Unity3D中实现简单的碰撞检测 - 汪海的实验室 - 博客频道 - CSDN.NET
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|