Этот метод работает независимо от типа вашей камеры или от того, как камера перемещается между кадрами.
Сначала, при первом нажатии на объект, получите плоскость в положении объекта, перпендикулярном направлению камеры:
Plane dragPlane = new Plane(Camera.main.transform.forward, transform.position);
Затем получите луч, исходящий из камеры, где находится мышь:
Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
Узнайте, где этот луч пересекается, используя Plane.Raycast
:
float enter = 0.0f;
if (dragPlane.Raycast(camRay, out enter))
{
Vector3 fingerPosition = camRay.GetPoint(enter);
Это дает вам положение в мировом пространстве, где вы можете считать, что палец находится в данный момент.Просто поместите объект туда:
transform.position = fingerPosition;
В целом это может выглядеть так:
void OnMouseDrag()
{
Plane dragPlane = new Plane(Camera.main.transform.forward, transform.position);
Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
float enter = 0.0f;
if (dragPlane.Raycast(camRay, out enter))
{
Vector3 fingerPosition = camRay.GetPoint(enter);
transform.position = fingerPosition;
}
}
Нет OnMouseDown
необходимо.
Альтернативой является отслеживаниекак fingerPosition
изменяется со временем, а Translate
преобразование, основанное на этом.Сохранение как можно большего количества математических единиц в мировых единицах облегчает задачу:
Vector3 prevFingerPosition = Vector3.zero;
// Same code as before but we use it in different places so it goes in its own method.
// If the Raycast fails, return a decent guess.
private Vector3 GetMouseOnPositionInWorldSpace()
{
Plane dragPlane = new Plane(Camera.main.transform.forward, transform.position);
Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
float enter = 0.0f;
if (dragPlane.Raycast(camRay, out enter))
{
return camRay.GetPoint(enter);
}
return prevFingerPosition;
}
void OnMouseDown()
{
prevFingerPosition = GetMouseOnPositionInWorldSpace();
}
void OnMouseDrag()
{
Vector3 fingerPosition = GetMouseOnPositionInWorldSpace();
transform.Translate(fingerPosition-prevFingerPosition);
prevFingerPosition = fingerPosition;
}
Кроме того, просто оставьте его как void OnMouseDrag()
и void OnMouseDown()
без private
, чтобы избежать проблем с Unity, которые не могут найтиметоды.
Существует проблема использования OnMouseDrag
для обработки перетаскивания объектов, заключающаяся в том, что если курсор перемещается слишком быстро, он может сдвинуться с объекта в пределах одного кадра и "упадет"." предмет.
Если это нежелательно, вы можете установить bool
равным true
в OnMouseDown
, который помнит, что объект был нажат, и переместить логику из OnMouseDrag
в * 1043.* где он может делать свое дело, если это bool
равно true
.И когда мышь отпущена, установите bool
обратно на false
.