Home > Software design >  Object only moving small amount in dragged direction [Unity 2D isometric]
Object only moving small amount in dragged direction [Unity 2D isometric]

Time:09-28

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;
}
  • Related