Единство - Несоответствие между OverlapBox и Gizmo - PullRequest
0 голосов
/ 01 августа 2020

Я хочу использовать OverlapBox, чтобы создать окно перед автомобилем и иметь возможность проверять столкновение по запросу. Я использую гизмо для рисования, чтобы увидеть размер и положение поля, чтобы убедиться, что размер и положение правильные.

Это мой код:

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

The issue occurs when the "vehicle" rotates - in the following picture I rotate the vehicle 90 degrees in the Y axis, the gizmo represents the box in the correct position, however the OverlapBox logic is ignoring such rotation (even though when the rotation of the object is passed in the function): введите описание изображения здесь

Как сделать так, чтобы OverlapBox работал должным образом, учитывая поворот и возможность представлять точную штуковину.

Заранее большое спасибо.

Ответы [ 2 ]

1 голос
/ 02 августа 2020

Удалось исправить проблему, проблема заключается в положении и повороте OverlapBox. Я думал, что вращение будет применяться с позиции игрового объекта (что, конечно, не имеет никакого смысла), произошло то, что вращение было применено к самому OverlapBox.

В моем случае, поскольку OverlapBox находится только в передней части транспортного средства, я заменил смещение Vector3 на поплавок OffsetZ (только по оси Z, как и в передней части транспортного средства) и изменил расчет положения OverlapBox в функции CheckForCollisions. следующим образом:

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

Это последний скрипт, который заставляет OverlapBox работать должным образом и соответствовать представлению гизмо:

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
}

Благодаря ответу xxmariofer в ответе Unity форумах, я опубликую здесь на всякий случай, если вы хотите использовать Vector3 в качестве смещения вместо float (только для одной оси):

Vector3 colliderPos = transform.TransformPoint(m_DetectorOffset);

Вот ссылка на сообщение : https://answers.unity.com/questions/1757338/mismatch-between-overlapbox-and-gizmo.html

0 голосов
/ 01 августа 2020

Почему бы вам не использовать коллайдер с флагом is Trigger = true? Перекрытие хорошо для редких вызовов, но если вы хотите проверять каждый кадр, вам лучше просто использовать триггер и метод OnTriggerEnter.

...