文/那个少年

在游戏战斗中,我们会用到各种各样的碰撞检测,来判断是否打中了目标

113613lxq52anl17epqdfx.png 比如扇形检测/圆形检测
113613wkypjed8ejrkvvtv.png 还有矩形检测,王者荣耀里后羿的大招就是一个很长的矩形碰撞体
这些在Unity3D引擎中其实都封装好了一些Collider组件去检测碰撞,但是我最近写帧同步算法的时候,发现U3D中的碰撞算法执行顺序不可控,会导致不同步的现象,所以就只好苦逼的自己写碰撞检测算法了。

我们游戏是一个3D动作类游戏,大概的碰撞可以分为几类
 

  • 圆柱体(把人/怪物的碰撞设定位一个圆柱体,U3D里是胶囊体,是为了解决一些边缘精度问题,但是我们游戏里的话圆柱就够用了)
  • 球体
  • 立方体


需要检测的碰撞有

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. }

计算方法是先找到矩形上离圆形最短距离u,然后再比较u是否小于圆形的半径r

(1)首先利用绝对值把 p - c 转移到第一象限,下图显示不同象限的圆心也能映射至第一象限,这不影响相交测试的结果:

113900cu6igy8e2i3nz633.png
(2)然后,把 v 减去 h,负数的分量设置为0,就得到圆心与矩形最短距离的矢量 u。下图展示了4种情况,红色的u是结果。

113900n6q3qx3hboqd13bz.png
最后要比较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检测应该就够用了


via:cnblogs

锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛