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