Unity C# 检测上面的所有游戏对象

Unity C# Detect all game objects above

我希望我的播放器检测第 8 层中的所有游戏对象。我找到了一个检测上面所有游戏对象的代码,但它只是在 x=0 线上检测,就像这些图中一样,

What It does

What I want

   RaycastHit[] hitsUp = Physics.RaycastAll(transform.position, transform.up, distance);
   RaycastHit[] hitsDown = Physics.RaycastAll(transform.position, -transform.up, distance);
   foreach (RaycastHit hit in hitsUp)
   {
       if (hit.collider.gameObject.layer == 8)
       {
            Physics.IgnoreCollision(hit.collider, GetComponent<Collider>());
       }
   }
   foreach (RaycastHit hit in hitsDown)
   {
       if (hit.collider.gameObject.layer == 8)
       {
            Physics.IgnoreCollision(hit.collider, GetComponent<Collider>(), false);
       }
   }

我该如何解决这个问题?感谢您的回复。

只需将图层蒙版滤镜添加到您的 Raycast 中即可。

int layerMask = 1 << 8; // - detects raycasts only on 8 layer
RaycastHit[] hitsUp = Physics2D.Raycast(transform.position, transform.up, distance, layerMask);
RaycastHit[] hitsDown = Physics.RaycastAll(transform.position, -transform.up, distance, layerMask);

foreach 不需要。

问题是你的 Raycast 只捕获玩家正上方的“命中”,因为它沿着一条直线。

您可以将所有游戏对象放在一个父对象中,然后遍历每个游戏对象,检查其层,然后检查它是在您的上方还是下方

类似这样的方法可行:

public Transform parent;
private Collider myCollider;

private void Start() 
{
    myCollider = GetComponent<Collider>();
}

private void DetectObjects()
{
    //Loop through each object above/below
    foreach (Transform child in parent)
    {
        GameObject childObj = child.gameObject;
        if (childObj.layer == 8) //Is the object on the correct layer?
        {
            if (child.position.y > transform.position.y) Physics.IgnoreCollision(childObj.GetComponent<Collider>(), myCollider);             //GameObjects above the player
            else if (child.position.y < transform.position.y) Physics.IgnoreCollision(childObj.GetComponent<Collider>(), myCollider, false); //GameObjects below the player
        }
    }
}

此外,您应该尝试存储 Collider 组件而不是使用 GetComponent<>(),因为它非常慢。

根据对象是否created/deleted,您也可以为它们存储碰撞器,这将大大提高代码的性能,例如:

public Transform parent;
private Collider myCollider;
private Collider[] objColliders;

private void Start() 
{
    myCollider = GetComponent<Collider>();
    //If any gameObject is inactive it can also be grabbed by adding true as a paramater
    objColliders = parent.GetComponentsInChildren<Collider>();
}

private void DetectObjects()
{
    GameObject childObj;
    //Loop through colliders
    for (int i = 0; i < objColliders.Length; i++)
    {
        childObj = objColliders[i].gameObject; //Store as gameObject reference
        if (childObj.layer == 8)
        {
            if (childObj.transform.position.y > transform.position.y) Physics.IgnoreCollision(objColliders[i], myCollider);             //GameObjects above the player
            else if (childObj.transform.position.y < transform.position.y) Physics.IgnoreCollision(objColliders[i], myCollider, false); //GameObjects below the player
        }
    }
}