Search Unity

Dragging, constrained to radius WITH decay

Discussion in 'Scripting' started by rxmarccall, Mar 4, 2015.

  1. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    Hey guys,
    I'm trying to make a script for dragging a 2D object that will follow the users mouse (or finger) while inside a radius, otherwise it is constrained to the outer edge of the radius. I've successfully accomplished this with the following script, but I'm now wanting to add a "decay" so that the dragging of the object feels more like a spring is being pulled out rather than free dragging and then just hitting a hard radius edge. (The dragged object stays less under the users finger the farther they drag away from the objects origin). When the user lets up the object springs back into its original position (which I have in some other code)

    I'm stumped on this and would appreciate some help.

    Code (CSharp):
    1.  
    2. // This is just a way to get input position using Easy Touch, consider it the same as MousePosition
    3. Vector3 mousePos = gesture.GetTouchToWorldPoint(gesture.pickedObject.transform.position);
    4.             distance = Vector3.Distance(mousePos, originPosition);
    5.             float radiusRatio = distance / dragMaxRadius;
    6.             if (radiusRatio > 1){
    7.                 radiusRatio = 1;
    8.             }
    9.  
    10. Vector3 newPos = mousePos - originPosition;
    11.             newPos.Normalize();
    12.  
    13.             newPos *= (dragMaxRadius * radiusRatio);
    14.             myParent.transform.position = originPosition + newPos;
    15.  
    Thanks in advance
     
  2. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    I'm not sure exactly how to help yet, but I know that using Mathf.lerp interpolates a smooth path.

    What kind of feature in the game is this suppose to be?
     
  3. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    For my application its a children's story book, and the user can drag the characters from their position on the page but I want to limit it to this radius, and when they let go it snaps back into place. Its mostly just to make the app more satisfying, a way to interact with the characters on the page.

    There are charlie brown apps that make the characters feel satisfying, they jiggle and such when you tap them or drag them a little. You can see here:


    I have it all working except I can't seem to understand what I might need to do mathematically to my code above to make the object I'm dragging "decay" its position to be less under my finger the farther I drag away from the objects origin position.
     
  4. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    You could set the position of the character to equal the mouse position (or finger position). Minus a float value on the Y and X axis. Then make the float variables more negative everytime the action is performed.

    If you post the code I could look at in unity and try to find a solution.
     
  5. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    Code (CSharp):
    1. // At the drag beginning
    2.     void On_DragStart(Gesture gesture)
    3.     {
    4.  
    5.         // Verification that the action on the object
    6.         if (gesture.pickedObject == gameObject)
    7.         {
    8.             // the world coordinate from touch
    9.             Vector3 position = gesture.GetTouchToWorldPoint(gesture.pickedObject.transform.position);
    10.             deltaPosition = position - myParent.transform.position;
    11.  
    12.         }
    13.     }
    14.     void On_Drag(Gesture gesture){
    15.          
    16. Vector3 mousePos = gesture.GetTouchToWorldPoint(gesture.pickedObject.transform.position);
    17.             distance = Vector3.Distance(mousePos, originPosition);
    18.             float radiusRatio = distance / dragMaxRadius;
    19.             if (radiusRatio > 1){
    20.                 radiusRatio = 1;
    21.             }
    22.  
    23.             Vector3 newPos = mousePos - originPosition;
    24.             newPos.Normalize();
    25.  
    26.             newPos *= (dragMaxRadius * radiusRatio);
    27.             myParent.transform.position = originPosition + newPos;
    28.      }
    29.      void On_DragEnd(Gesture gesture){
    30.      
    31. // Recoil the sticker back into place
    32.         if (isTween){
    33.             DOTween.To(() => myParent.transform.position, x => myParent.transform.position = x, originPosition, springBackTime)
    34.                .SetEase(Ease.OutElastic).OnComplete(ResetSortingOrder);
    35.         }
    36.         else{
    37.             transform.position = originPosition;
    38.         }
    39.    }
    40.  
    41.  
    Thats basically all of the code, I am however using an asset called Easy Touch to get touch events, such as On_Drag, etc. But these could be easily changed out for normal mouse events for testing. I'm also using a tween library (DOTween) to recoil the sticker back in place when the user lets up.

    Hopefully that gives you something to work with. (Note: again this is for a 2D sprite)
     
    Last edited: Mar 5, 2015
  6. roger0

    roger0

    Joined:
    Feb 3, 2012
    Posts:
    1,208
    Ah. Well I cant run the code without having access and knowledge to the assets your using.

    You could try to using Mathf.MoveTowards, or Mathf.lerp and have the speed decrease in the OnDrag function until it reaches 0. It would be more simple than my previous suggestion.
     
  7. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    Thanks for the reponses, will try that out hopefully tonight after school when I finally have some time.