效果需求

现在的情况是这样的,要设计我们的角色拾取物品的功能

目前有以下两点问题需要解决

  • 获取角色身边的对象信息
  • 判断是否为物品,并且是否在可拾取角度内

获取角色附近物体的信息有很多方法可以解决,可以使用射线检测,但是射线检测的范围只有一条线的大小,无法直接使用,如果先判定角色与物品的距离和角度后再用射线检测呢?可以是可以,但是会消耗太多不必要是性能,因为我们只有在按下拾取按键的瞬间,才会使用到这个办法。

经过查阅资料,发现有一种方法是通过同时发射不同角度的射线,以达成扇形射线检测的效果,如图,但该方法有一个致命的缺点,就是只能从同一高度发出射线,如果物体和射线不在同一个高度则会无法检测到,虽然也可以再加一层射线循环,让它在纵向也发射射线,但感觉并不是我想要的方法。

多角度射线检测 多角度射线检测.png

之后我又找到了Physics下的体型检测方法
见下图,来自https://www.cnblogs.com/SouthBegonia/p/11732340.html

他的原理是允许我们使用一个立方体区域BoxCast、球体区域SphereCast、胶囊体区域CapsuleCast来检测物体,但这前三种方法只能检测单个物体,如果想检测射线上的多个物体需要在后面加ALL的方法。

体型检测.png

这个方法可以满足我们的需求了,但我测试后发现我找不到这个的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:由于我还不会测这个方法和与其他方法相比,它的性能消耗差距有多少,所以本方法很可能不是最优解法,本方法仅供一个思路参考