Это один из способов сделать то, о чем вы просите.
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), вы добавляете смещение к hit.point
по одной из 3 осей.
bounds.extents
дает вам половину лиц, используя bounds.extents.x
, bounds.extents.y
и bounds.extents.z
. Вы хотите, чтобы смещение составляло только половину длины грани, потому что, когда вы перемещаете куб с помощью мыши, куб находится в его центре.
Вот пример: