当移动到 Unity3D 中的 RaycastHit 点时,使 object 与某些其他 object 发生碰撞?

Make an object collide with certain other objects when moved to RaycastHit point in Unity3D?

我正在使用鼠标指针的光线投射制作一个简单的建筑系统。将要放置的 object 移动(并在单击时克隆)到射线的 RaycastHit.point,但我希望它与自身类型的 object 完全碰撞,移动它相对于命中点的位置。 object 可以与 gif 中所示的地形相交,但不应位于已放置的墙块内部。我尝试使用 hit.distance 但无法确定检测结果,因为 object 已经位于碰撞点。我应该尝试检测位置应该如何相对于命中点移动,还是应该以某种方式让 MeshCollider 在不断移动到 RaycastHit.point 时工作?

这是完成您所要求的一种方法。

private void Update()
{
    Vector3 hitPosition = Vector3.zero;
    Ray ray = _camera.ScreenPointToRay(Input.mousePosition);

    if (Physics.Raycast(ray, out RaycastHit hit))
    {
        hitPosition = hit.point; // 0
        if (hit.transform.gameObject.CompareTag("cube")) // 1
            hitPosition = ComputeHit(hit, hitPosition);
    }

    _current.transform.position = hitPosition;
}

private Vector3 ComputeHit(RaycastHit hit, Vector3 currentPosition)
{
    var bounds = hit.transform.GetComponent<MeshRenderer>().bounds; // 2

    Faces face = GetFace(hit); // 3
    switch (face)
    {
        case Faces.Up:
            currentPosition += new Vector3(0, bounds.extents.x, 0);
            break;
        case Faces.Down:
            currentPosition += new Vector3(0, -bounds.extents.x, 0);
            break;
        case Faces.East:
            currentPosition += new Vector3(bounds.extents.x, 0, 0);
            break;
        case Faces.West:
            currentPosition += new Vector3(-bounds.extents.x, 0, 0);
            break;
        case Faces.North:
            currentPosition += new Vector3(0, 0, bounds.extents.x);
            break;
        case Faces.South:
            currentPosition += new Vector3(0, 0, -bounds.extents.x);
            break;
    }

    return currentPosition;
}

public Faces GetFace(RaycastHit hit)
{
    Vector3 res = hit.normal - Vector3.up;

    if (res == new Vector3(0, -1, -1))
        return Faces.South;

    if (res == new Vector3(0, -1, 1))
        return Faces.North;

    if (res == new Vector3(0, 0, 0))
        return Faces.Up;

    if (res == new Vector3(1, 1, 1))
        return Faces.Down;

    if (res == new Vector3(-1, -1, 0))
        return Faces.West;

    if (res == new Vector3(1, -1, 0))
        return Faces.East;

    return Faces.Nothing;
}

public enum Faces
{
    Nothing,

    Up,
    Down,
    East,
    West,
    North,
    South
}

我会进一步解释:

在您的 Update 方法中,一旦您检测到 hit.point 位置 // 0,您可以检查您是否瞄准立方体 // 1。我不知道你如何在实例化后管理它们,但我添加了一个名为 cube 的标签。 它可以是任何名称或图层。 它也可以是一个组件,并使用 hit.transform.GetComponent<...>() 方法检查该组件是否存在。

然后,你得到瞄准的立方体边界 // 2 并使用法线来确定你瞄准的方向 // 3

从这里开始,根据目标面(6 个中的一个),在 3 个轴之一上为 hit.point 添加偏移。

bounds.extents给你一半的脸,使用bounds.extents.xbounds.extents.ybounds.extents.z。 你只希望偏移是面的一半长度,因为当你用鼠标移动你的立方体时,立方体的位置是在它的中心。

这是一个例子: