效果需求
现在的情况是这样的,要设计我们的角色拾取物品的功能
目前有以下两点问题需要解决
- 获取角色身边的对象信息
- 判断是否为物品,并且是否在可拾取角度内
获取角色附近物体的信息有很多方法可以解决,可以使用射线检测,但是射线检测的范围只有一条线的大小,无法直接使用,如果先判定角色与物品的距离和角度后再用射线检测呢?可以是可以,但是会消耗太多不必要是性能,因为我们只有在按下拾取按键的瞬间,才会使用到这个办法。
经过查阅资料,发现有一种方法是通过同时发射不同角度的射线,以达成扇形射线检测的效果,如图,但该方法有一个致命的缺点,就是只能从同一高度发出射线,如果物体和射线不在同一个高度则会无法检测到,虽然也可以再加一层射线循环,让它在纵向也发射射线,但感觉并不是我想要的方法。
多角度射线检测
之后我又找到了Physics下的体型检测方法
见下图,来自https://www.cnblogs.com/SouthBegonia/p/11732340.html
他的原理是允许我们使用一个立方体区域BoxCast、球体区域SphereCast、胶囊体区域CapsuleCast来检测物体,但这前三种方法只能检测单个物体,如果想检测射线上的多个物体需要在后面加ALL的方法。
这个方法可以满足我们的需求了,但我测试后发现我找不到这个的Debug.Draw方法,我无法直观的看到我所绘制检测的区域,这让我非常的纠结...
但好在,最后我找到了一个最简单的方法
Physics.OverlapSphere
解决办法
Physics.OverlapSphere(Vector3 position, float radius, int layerMask)
- position - 球心位置
- radius - 球半径
- layerMask - 在所指定的Layer层上进行检测
该方法可以获取以一个点作为中心,其绘制的圆形大小内的所有带有collider组件的对象。
获取到后判断tag与角度即可~
代码部分
public void pickUp()
{
Debug.DrawRay(transform.position, transform.forward * 2.0f, Color.green);
if(keyboard.eKey.wasPressedThisFrame)
{
Collider[] colls = Physics.OverlapSphere(transform.position, 2f); //获取周围物品
foreach (Collider collider in colls)
{
if (collider.gameObject.tag == "Pick" && Vector3.Angle(collider.gameObject.transform.position - transform.position, transform.forward) <= 45)
{
print("GET!");
Destroy(collider.gameObject, 1f);
}
}
}
使用方法
挂载在你的角色上并在update下调用即可
注意我使用了Input System,记得更改你的按键获取方法。
PS:由于我还不会测这个方法和与其他方法相比,它的性能消耗差距有多少,所以本方法很可能不是最优解法,本方法仅供一个思路参考