unity3d 如何知道一个世界点是否在一个由位置(Vector3)、缩放(Vector3)和旋转(四元数)给定的框内?

zzwlnbp8  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(165)

我有一个对象,它的Transform的位置、旋转和缩放表示一个长方体/立方体的位置、旋转和缩放。
我想知道Vector3给出的世界点是否在这个盒子里。
我可以通过附加一个具有默认比例的立方体作为它的子对象,或者使用以下Gizmo,来确定此虚拟框的位置:

private void OnDrawGizmos()
{
    Gizmos.color = Color.blue;
    Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale);
    Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
}

我想说的是,如果一个世界的立场(例如:new Vector3(0.98f, 3.2f, 1.26f)位于Gizmo将绘制的区域内部或外部。

我尝试了什么?

  • 我知道这可以很容易地解决使用碰撞器,例如BoxCollider.ClosestPoint,但在我的场景中,我会创建大量的游戏对象在运行时代表一个“labirynth”Map,他们不应该有碰撞器,因为没有点的Map有物理,它可能会干扰游戏的其他部分。
  • 绘制的网格或网格渲染的边界可能与我想测试的框不完全匹配。视觉表示可能与逻辑不同,所以我也不能使用它。
  • 我尝试使用thatObjectWithGizmo.InverseTransformPoint(myWorldPoint),期望它能从全局转换为本地,并按以下方式进行测试:
public class ScriptToTestPoint : MonoBehaviour
{
    public Transform thatObjectWithGizmo;
    public Vector3 myWorldPoint;

    public void OnDrawGizmos()
    {
        Vector3 resultingPosition = thatObjectWithGizmo.InverseTransformPoint(myWorldPoint);
        bool isInside = new Bounds(thatObjectWithGizmo.position, thatObjectWithGizmo.lossyScale).Contains(resultingPosition);

        Gizmos.color = isInside ? Color.red : Color.white;
        Gizmos.DrawSphere(transform.position, 1f);
    }
}

但结果是错的。
我怎样才能做这个测试?

q3qa4bjr

q3qa4bjr1#

真丢人!经过一些反复试验,试图意识到为什么当盒子在默认位置时结果是有效的,而当移动和旋转时却不是,结果证明一切都很好,但我对照对象的世界位置和比例测试了这个点(加分:我忽略了它的旋转)。
似乎是这样的:

Vector3 resultingPosition = thatObjectWithGizmo.InverseTransformPoint(myWorldPoint);

正在将世界点正确地转换为局部点,但我误解了应该如何检查它,我通过对世界位置进行测试:

// Wrong
bool isInside = new Bounds(thatObjectWithGizmo.position, thatObjectWithGizmo.lossyScale).Contains(resultingPosition);

修复很简单,我需要测试对一个局部边界:

// Correct
bool isInside = new Bounds(Vector3.zero, Vector3.one).Contains(resultingPosition);

这样它就能准确地给予我想要的信息。

相关问题