我想使用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,表示为小发明:
问题发生在“车辆”旋转时-在下图中,我将车辆沿Y轴旋转了90度,小控件表示框处于正确的位置,但是OverlapBox逻辑忽略了这种旋转(即使对象的旋转在函数中传递):
考虑到旋转并能够代表准确的小控件,如何使OverlapBox正常工作。
非常感谢。
答案 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方法。