碰撞檢測問題及解決

2022-03-18 03:52:26 字數 1534 閱讀 9973

在unity3d中,碰撞可以形象理解為現實世界中的碰撞,並且由於物理引擎的模擬,使碰撞物體也會如現實世界一樣產生相同的碰撞結果,如運動軌跡的改變、**等,總之碰撞的結果為產生我們不期望的物體運動行為。為了避免產生這種碰撞,就需要進行碰撞檢測。

碰撞檢測的原理是在物體移動的前方放置乙個虛擬物體,它與物體進行同步運動。如果有障礙,則要先與虛擬物體碰撞。一旦檢測到虛擬物體的碰撞,則運動物體停止移動。

圖 - 1 physic.raycast射線掃瞄api

圖 - 2 碰撞檢測

圖 - 3 呼叫碰撞的實現

以上實現經過分析,原理想法上沒問題,就是每隔乙個固定頻率後進行射線碰撞檢測。但是效果上卻總是會在一些偶然的情況下發生碰撞,具體情形如下截圖:

圖 - 4 碰撞導致不期望的運動

經過分析,發現update雖然是每幀執行的,但是unity3d的fps——每秒的幀數,是變化的,它的值取決於渲染場景的面數;渲染速度又受機器的效能特別是cpu、記憶體、顯示卡不同而表現很大的差異。如果場景中渲染的面數太多,並且機器配置不夠好,可能導致fps很低,從而使渲染的兩幀之間時間間隔很大,而在這個間隔內,碰撞已經發生,從而出現了上面的碰撞現象。

對於物理運動中需要進行固定頻率的動作,unity3d提供了fixedupdate方法,這個頻率是系統引數,可以更改。因此,我們使用fixedupdate來替換update可解決此問題。

如圖 - 2 碰撞檢測實現中,雖然多加了幾條射線,但畢竟只是物體中的個別點。在我們的場景中,物體都是規則的且正常運動規律顯著,所以只需要把幾個特徵點找到然後分別進行射線檢測即可。但是這個畢竟是存在缺陷的,如果能夠對物體整個面進行檢測,那就完美了。

幸運的是,自unity3d 版本3以來,針對剛體的碰撞檢測問題,專門提供了rigidbody.sweeptest方法。需要注意的是physics.raycast裡面有乙個層的概念,而且不是必須剛體才會被檢測到;而rigidbody.sweeptest則只檢測剛體碰撞,與層無關。

經過以上分析,可以知道碰撞檢測會用到關鍵性方法rigidbody.sweeptest,它的api如下截圖:

圖 - 5 剛體碰撞檢測的api

改善後的實現如下截圖:

圖 - 6 改善性實現**

經過試驗,改善後的實現可以很好解決碰撞問題

碰撞檢測問題

我們在進行碰撞檢測的時候,可以使用collider方法 即碰撞器 通常使用collider時,兩物體檢測碰撞器時,兩物體中至少有乙個應為剛體元件。我們一般建議移動物體設定為剛體,因為物體長時間不運動其剛體元件可能會休眠。collider通常是根據判斷目標的tag來執行不同的方法。以下為判斷碰撞後的方...

碰撞檢測 膠囊體碰撞檢測

膠囊體 給定一條線段l,所有道l的距離為r的點的集合。由定義可知,膠囊體由半徑r和線段l標識。檢測兩個膠囊體是否發生碰撞,即檢測兩條線段l1 l2的最短距離d是否大於l1 l2的半徑r1 r2之和,d r1 r2 則未碰撞,否則發生碰撞。設線段l1端點為a1 a2,線段l2端點為b1 b2,號表示兩...

Unity碰撞檢測

碰撞個必要條件為兩個角色必須都掛載 rigibody 剛體元件,至少乙個角色掛載 collider指令碼 第一種 觸發器,必須開啟 collider的 istrigger 為 true 兩個碰撞物件會相互穿過 void ontriggerenter collider collider 開始觸發器 v...