Unity3D-游戲中的技能碰撞檢測


在游戲戰斗中,我們會用到各種各樣的碰撞檢測,來判斷是否打中了目標

比如扇形檢測/圓形檢測

 

還有矩形檢測,王者榮耀里后羿的大招就是一個很長的矩形碰撞體

 

這些在Unity3D引擎中其實都封裝好了一些Collider組件去檢測碰撞,但是我最近寫幀同步算法的時候,發現U3D中的碰撞算法執行順序不可控,會導致不同步的現象,所以就只好苦逼的自己寫碰撞檢測算法了。

我們游戲是一個3D動作類游戲,大概的碰撞可以分為幾類

  1. 圓柱體(把人/怪物的碰撞設定位一個圓柱體,U3D里是膠囊體,是為了解決一些邊緣精度問題,但是我們游戲里的話圓柱就夠用了)
  2. 球體
  3. 立方體

需要檢測的碰撞有

1.檢測圓柱體跟球體的碰撞

2.立方體跟圓柱體的碰撞

 

具體實現:

1.球體跟圓柱體碰撞檢測

 1     /// <summary>
 2     /// 檢測球體跟圓柱體碰撞
 3     /// </summary>
 4     /// <param name="x1">球體X</param>
 5     /// <param name="y1">球體Y</param>
 6     /// <param name="z1">球體Z</param>
 7     /// <param name="r1">球體半徑</param>
 8     /// <param name="x2">圓柱體X</param>
 9     /// <param name="y2">圓柱體Y</param>
10     /// <param name="z2">圓柱體Z</param>
11     /// <param name="r2">圓柱半徑</param>
12     /// <param name="h2">圓柱體高度</param>
13     public static bool CheckCircleAndCylinderCollider(float x1, float y1, float z1, float r1,
14     float x2, float y2, float z2, float r2, float h2) 15  { 16 float dx = x2 - x1; 17 float dy = y2 - y1; 18 float dz = z2 - z1; 19 float disSqua = (dx * dx) + (dz * dz); 20 float rSqua = (r1 + r2) * (r1 + r2); 21 bool heightCheck = Math.Abs(y1 - y2) < r1 + h2 / 2; 22 return heightCheck && disSqua < rSqua; 23 }

1.檢測兩個圓有沒有相交

2.檢測Y軸的距離是否小於球半徑+圓柱體高度的一半

這里是把球體也當成了圓柱體進行檢測,好處就是:效率高。 缺點是:不精確,沒有考慮X,Z軸的旋轉

但由於我們游戲中圓柱體不會有X,Z軸的旋轉,所以這樣的做法是最高效的

精確性問題:把圓柱體變成膠囊體,兩端用兩個球體來計算檢測,這樣會更精確,同時性能也會降低

 

2.立方體跟圓柱體的碰撞

這里先把問題簡化成矩形跟圓形的碰撞檢測

計算方法是先找到矩形上離圓形最短距離u,然后再比較u是否小於圓形的半徑r

 

1. 首先利用絕對值把 p - c 轉移到第一象限,下圖顯示不同象限的圓心也能映射至第一象限,這不影響相交測試的結果:

 

 

2. 然后,把 v 減去 h,負數的分量設置為0,就得到圓心與矩形最短距離的矢量 u。下圖展示了4種情況,紅色的u是結果。

 

 最后要比較u和r的長度,若距離少於r,則兩者相交。可以只求u的長度平方是否小於r的平方 

 

具體做法可以參考這里:https://www.zhihu.com/question/24251545

 

對於AABB包圍盒,這樣就已經可以檢測碰撞了,但是如果矩形是旋轉的OBB包圍盒呢?

我這里是實現了一個OBB的包圍盒類,記錄了坐標,角度,碰撞檢測的時候先把圓的角度旋轉到OBB的坐標系里

利用旋轉公式:

x2 = x * Mathf.Cos(rad) - z * Mathf.Sin(rad);

z2= x * Mathf.Sin(rad) + z * Mathf.Cos(rad);

然后再用那篇文章里說的方式計算矩形跟圓是否相交

最后再通過兩者 Y軸的距離 < (圓柱體高度+立方體的高度)/2 ,如果小於則相交

這種方法的優勢:效率高,而且精確

缺點是這個3D的OBB只能沿Y軸旋轉,不過也夠用了 

 

如果像王者榮耀類型的游戲,感覺不需要擴展到3D,2D檢測應該就夠用了

 


免責聲明!

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



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