简体   繁体   中英

Scaling a 2d game object with mouse drag in unity

So I have had a few attempts and posts about this but have still not been successful. The behaviour I want is this:

There is a circle (sphere) I want the player to be able to click and drag it outwards to make it larger, or drag inwards to make it smaller. Previously, I was scaling the object based on the inital dragging point, but this was giving me no way to scale the shape back down.. only make it larger. I figured I need to calculate whether we should be scaling up or down, based on the direction of the drag in relation to the centre of the shape. To figure this out, we need to check the position of the mouse, while dragging, compare it to the previous frame and decide whether we are closer or further away from the centre. If we are closer, then we are dragging inwards and we should scale the object down (make it smaller). Id we are further away, then we are moving outwards and should be scaling up (make it larger). I'm having a couple of problems. I don't seem to be able to get the circle to scale down at all. The detection for the direction of the drag seems to be flawed as it seems my bool for isDraggingOut is basically always true, I can't understand why. The other problem I'm having is that every time I click the circle, it snaps back to it's initial size.

I am trying to take the following steps in my code:

  1. On Mouse drag: check where current position of the mouse is
  2. check distance of previous position of the mouse
  3. check distance of current position
  4. determine whether player is dragging in or out. If current distance is more than the distance in the previous frame, we are dragging out
  5. If this is true, then calculate the distance between the drag start point and the current position of the mouse, and scale accordingly
  6. If the distance is less than the previous frame then we are dragging in
  7. then calculate the distance between the drag start point and the current position of the mouse, and scale accordingly (here, i have tried to apply an inverse calculation of the upscaling calculation - this could be wrong)
  8. The last thing I do in my code is make the current position equal to previousPosition variable, so that in the next frame it can be compared.

Any help would be appreciated as I am really struggling with this one.

{
    public Vector3 temp;
    public Vector3 dragStartingPoint;
    public Vector3 centreOfShape;
    public Vector3 currentDragPosition;
    public Vector3 previousDragPosition;
    public bool isDraggingOut;
    public float previousDistance;
    public float currentDistance;
    public float amountDragged;
    public float clampedAmountDragged;


    private void Awake()
    {
        centreOfShape = transform.position;

    }

    private void OnMouseDown()
    {
        dragStartingPoint = Input.mousePosition;
    }


    private void OnMouseDrag()
    {
        //check where current position is
        currentDragPosition = (Input.mousePosition);

        //check distance of previous position
        previousDistance = Vector3.Distance(previousDragPosition, centreOfShape);

        //check distance of current position
        currentDistance = Vector3.Distance(currentDragPosition, centreOfShape);

        //determine whether player is dragging in or out. If current distance is 
        // more than the distance in the previous frame, we are dragging out
        if (currentDistance > previousDistance)
        {
            isDraggingOut = true;

        }

        else
        {
            isDraggingOut = false;
        }


        if (isDraggingOut == true)
        {
           amountDragged = Vector3.Distance(currentDragPosition, dragStartingPoint);

            // set minimum and maximum drag amount and store in clampedAmountDragged variable

            clampedAmountDragged = Mathf.Clamp(amountDragged, 100f, 300f);

            // set amountDragged to clampedAmount to apply minimum and maximum

            amountDragged = clampedAmountDragged;

            temp = transform.localScale;
            temp.x = amountDragged / 100;
            temp.y = amountDragged / 100;


            //make scale of object equal to temp variable
            transform.localScale = temp;


        }
        // else we are dragging in

        else if (isDraggingOut == false)
        {
            amountDragged = Vector3.Distance(currentDragPosition, dragStartingPoint);

            // set minimum and maximum drag amount and store in clampedAmountDragged variable

            clampedAmountDragged = Mathf.Clamp(amountDragged, 100f, 300f);

            // set amountDragged to clampedAmount to apply minimum and maximum

            amountDragged = clampedAmountDragged;

            amountDragged = amountDragged - 300;

            amountDragged = Mathf.Abs(amountDragged);

            temp = transform.localScale;
            temp.x = amountDragged / 100;
            temp.y = amountDragged / 100;


            //make scale of object equal to temp variable
            transform.localScale = temp;
        }



       currentDragPosition = previousDragPosition;
    }
}```

Firstly you need to make it clear if your game is in 2d or 3d space.Note that Input.mousePosition returns the 2d position on screen space, not world space. I believe this is why the sphere's size is resetting. You are probably looking for Camera.main.ScreenToWorldPoint(Input.mousePosition) .

This will give you your world space cursor position. Store the distance between CenterOfShape and Camera.main.ScreenToWorldPoint(Input.mousePosition) in OnMouseDown .Then In OnMouseDrag() , do a new distance check and find difference the the new distance with the one stored earlier. take this difference and add it uniformly to the sphere's scale.

I hope this helped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM