这是按照您的要求做的一种方式。
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
}
我会进一步解释:
在您的更新方法中,一旦您检测到hit.point 位置// 0 的位置,您就可以检查您是否瞄准了一个立方体// 1。我不知道你在实例化后如何管理它们,但我添加了一个名为cube 的标签。
它可以是任何名称或图层。
也可以是一个组件,用hit.transform.GetComponent<...>()方法检查这个组件是否存在。
然后,您获得目标立方体边界// 2 并使用法线确定您瞄准的方向// 3。
从这里开始,取决于目标面(6 个中的一个),您在 3 个轴之一上为 hit.point 添加偏移量。
bounds.extents 给你一半的脸,使用bounds.extents.x、bounds.extents.y 和bounds.extents.z。
您只希望偏移量为面的一半长度,因为当您用鼠标移动立方体时,立方体的位置在它的中心。
这是一个例子: