Unity - OverlapBox 和 Gizmo 之间的不匹配

Unity - Mismatch between OverlapBox and Gizmo

我想使用 OverlapBox 在车辆前面创建一个框,并能够按需检查碰撞。 我使用 draw gizmo 来查看框的大小和位置,以确认大小和位置是否正确。

这是我的代码:

public class TestCollision : MonoBehaviour
{
[Header("Collision")]
public Vector3 m_DetectorOffset = Vector3.zero;
public Vector3 m_DetectorSize = Vector3.zero;

private LayerMask m_LayerMask;
private Renderer m_Renderer = null;

void Start()
{
    m_LayerMask = (1 << LayerMask.NameToLayer("Pedestrian")) | (1 << LayerMask.NameToLayer("Vehicle"));

    m_Renderer = GetComponent<Renderer>();
    m_Renderer.material.color = Color.green;
}

private void FixedUpdate()
{
    if (CheckForCollisions())
        m_Renderer.material.color = Color.red;
    else
        m_Renderer.material.color = Color.green;
}

public bool CheckForCollisions()
{
    Vector3 colliderPos = transform.position + m_DetectorOffset;

    Collider[] colliders = Physics.OverlapBox(colliderPos, m_DetectorSize, transform.rotation, m_LayerMask);

    if (colliders.Length == 1)
    {
        // Ignore collision with itself
        if (colliders[0].gameObject == gameObject)
            return false;

        return true;
    }

    if (colliders.Length > 0)
        return true;

    return false;
}

#if UNITY_EDITOR
protected virtual void OnDrawGizmos()
{
    Gizmos.color = Color.red;
    Gizmos.matrix = transform.localToWorldMatrix;
    Gizmos.DrawWireCube(m_DetectorOffset, m_DetectorSize * 2.0f);
}
#endif
}

如果我不旋转“车辆”,这个脚本效果很好 - 在图片中,蓝色立方体是我想要检测的物体,green/red 立方体是车辆,红色线框是Gizmo 代表的 OverlapBox:

当“车辆”旋转时出现问题 - 在下图中,我将车辆沿 Y 轴旋转 90 度,gizmo 代表正确位置的框,但是 OverlapBox 逻辑忽略了这种旋转(甚至虽然当对象的旋转在函数中传递时):

如何使 OverlapBox 在考虑旋转的情况下正常工作并能够表示准确的 Gizmo。

非常感谢。

为什么不使用带 is Trigger = true 标志的对撞机? 重叠对于罕见的调用是有好处的,但如果你想检查每一帧,你最好只使用触发器和 OnTriggerEnter 方法。

设法解决了问题,问题是 OverlapBox 的位置和旋转。我认为旋转将从游戏对象的位置应用(当然这没有任何意义),实际情况是旋转应用于 OverlapBox 本身。

在我的例子中,由于 OverlapBox 仅在车辆的前部,我将 Vector3 偏移替换为浮动 OffsetZ(仅在 Z 轴上,如在车辆前部),并更改了计算OverlapBox在CheckForCollisions函数中的位置如下:

Vector3 colliderPos = transform.position + (transform.forward * m_DetectorOffsetZ);

这是使 OverlapBox 正常工作并匹配 gizmo 表示的最终脚本:

public class TestCollision : MonoBehaviour
{
[Header("Collision")]
public Vector3 m_DetectorOffset = Vector3.zero;
public Vector3 m_DetectorSize = Vector3.zero;
public float m_DetectorOffsetZ = 0.0f;

private LayerMask m_LayerMask;
private Renderer m_Renderer = null;

void Start()
{
    m_LayerMask = (1 << LayerMask.NameToLayer("Pedestrian")) | (1 << LayerMask.NameToLayer("Vehicle"));

    m_Renderer = GetComponent<Renderer>();
    m_Renderer.material.color = Color.green;
}

private void FixedUpdate()
{
    if (CheckForCollisions())
        m_Renderer.material.color = Color.red;
    else
        m_Renderer.material.color = Color.green;
}

public bool CheckForCollisions()
{
    Vector3 colliderPos = transform.position + (transform.forward * m_DetectorOffsetZ);

    Collider[] colliders = Physics.OverlapBox(colliderPos, m_DetectorSize, transform.rotation, m_LayerMask);

    if (colliders.Length == 1)
    {
        // Ignore collision with itself
        if (colliders[0].gameObject == gameObject)
            return false;

        return true;
    }

    if (colliders.Length > 0)
        return true;

    return false;
}

#if UNITY_EDITOR
protected virtual void OnDrawGizmos()
{
    Gizmos.color = Color.red;
    Gizmos.matrix = transform.localToWorldMatrix;
    Vector3 pos = Vector3.zero;
    pos.z = m_DetectorOffsetZ;
    Gizmos.DrawWireCube(pos, m_DetectorSize * 2.0f);
}
#endif
}

感谢 Unity 回答论坛中 xxmariofer 的回复,我将 post 放在这里,以防万一你想使用 Vector3 作为偏移量而不是浮点数(仅用于一个轴):

Vector3 colliderPos = transform.TransformPoint(m_DetectorOffset);

这是 link 到 post: https://answers.unity.com/questions/1757338/mismatch-between-overlapbox-and-gizmo.html