Unity-OverlapBox和Gizmo之间不匹配

时间:2020-08-01 17:09:35

标签: c# unity3d collision-detection

我想使用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
}

如果我不旋转“车辆”,此脚本将非常有用-在图片中,蓝色立方体是我要检测的对象,绿色/红色立方体是车辆,红色线框是OverlapBox,表示为小发明: enter image description here

问题发生在“车辆”旋转时-在下图中,我将车辆沿Y轴旋转了90度,小控件表示框处于正确的位置,但是OverlapBox逻辑忽略了这种旋转(即使对象的旋转在函数中传递): enter image description here

考虑到旋转并能够代表准确的小控件,如何使OverlapBox正常工作。

非常感谢。

2 个答案:

答案 0 :(得分:2)

设法解决该问题,问题在于OverlapBox的位置和旋转。我以为旋转将从游戏对象的位置开始应用(当然这没有任何意义),发生的是旋转已应用于OverlapBox本身。

在我的情况下,由于OverlapBox仅位于车辆的前部,因此我将Vector3偏移量替换为浮点OffsetZ(仅在Z轴上与车辆的前部相同),并更改了位置计算CheckForCollisions函数中OverlapBox的显示,如下所示:

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 Answers论坛中对xxmariofer的回复,我将在此处发布,以防万一,如果您想将Vector3用作偏移量而不是浮点数(仅用于一个轴),请使用以下行:

Vector3 colliderPos = transform.TransformPoint(m_DetectorOffset);

以下是该帖子的链接: https://answers.unity.com/questions/1757338/mismatch-between-overlapbox-and-gizmo.html

答案 1 :(得分:0)

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