So I'm currently working on an isometric 2D game and I'm trying to drag objects with the mouse. I've added the script below after following some tutorials but the object only moves a little bit in the direction it's being dragged. I have no idea why the object is not just following the mouse's coordinates but if you need any other info I don't mind providing.
private void onm ouseDown()
{
mouseOffset = MouseWorldPos() - (Vector2)transform.position;
}
private void onm ouseDrag()
{
transform.position = MouseWorldPos() - mouseOffset;
}
private Vector2 MouseWorldPos()
{
Vector2 mousePos = Input.mousePosition;
return Camera.main.ScreenToViewportPoint(mousePos);
}
CodePudding user response:
why do you convert to Viewport
coordinates?
Viewport space is normalized and relative to the camera. The bottom-left of the camera is (0,0); the top-right is (1,1). The z position is in world units from the camera.
=> You first do
mouseOffset = MouseWorldPos() - (Vector2)transform.position;
which can maximum be a position 0
to √(2)
away from the transform.position
.
Then you do
transform.position = MouseWorldPos() - mouseOffset;
which basically keeps it at your original position - √(2)
in any direction.
You probably would rather want to do something like e.g.
private readonly struct DragInfo
{
public Plane Plane { get; }
public Vector3 StartHitPoint { get; }
public Vector3 OriginalPosition { get; }
public DragInfo(Plane plane, Vector3 startHitPoint, Vector3 originalPosition)
{
Plane = plane;
StartHitPoint = startHitPoint;
OriginalPosition = originalPosition;
}
}
private DragInfo? dragInfo;
private Camera mainCamera;
private void onm ouseDown()
{
if(!mainCamera) mainCamera = Camera.main;
var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
var plane = new Plane(-mainCamera.transform.forward, transform.position);
if(!plane.Raycast(ray, out var hitDistance)) return;
var startPoint = ray.GetPoint(hitDistance);
dragInfo = new DragInfo(Plane, startPoint, transform.position);
}
private void onm ouseDrag()
{
if(!dragInfo.HasValue) return;
var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if(!dragInfo.Plane.Raycast(ray, out var hitDistance)) return;
var currentPoint = ray.GetPoint(hitDistance);
var delta = currentPoint - dragInfo.StartHitPoint;
transform.position = dragInfo.OriginalPosition delta;
}
private void onm ouseUp()
{
dragInfo = null;
}