在Unity3D中,当移动到RaycastHit点时,使一个对象与某些其他对象发生碰撞?

问题描述 投票:0回答:1

我正在使用鼠标指针的Raycasting制作一个简单的建筑系统。要放置的对象被移动(并在点击时克隆)到射线的RaycastHit.point,但我希望它能与自己类型的对象完全碰撞,相对于命中点移动其位置。物体可以像gif中所示的那样与地形相交,但不应该在已经放置的墙块内。我试着用hit.distance来检测,但无法弄清楚,因为对象已经被定位在碰撞点上了。我是否应该尝试检测相对于碰撞点的位置应该如何移动,或者我应该以某种方式使MeshCollider在它不断移动到RaycastHit.point时工作?

alt text

unity3d collision-detection collision raycasting
1个回答
2
投票

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

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个中的一个),你添加一个偏移到你的。hit.point 在3条轴的其中一条上。

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

下面是一个例子:

Cubes example

© www.soinside.com 2019 - 2024. All rights reserved.