Search Unity

rigidbody2D dragable script,

Discussion in '2D' started by ianjgrant, Nov 19, 2013.

  1. ianjgrant

    ianjgrant

    Joined:
    Mar 11, 2013
    Posts:
    28
    Hi, Is there a rigidbody2D dragable script, for easy use on chains of sprites? I still crave one that is multi-touch savvy...
    Kind regards Ian
     
  2. ianjgrant

    ianjgrant

    Joined:
    Mar 11, 2013
    Posts:
    28
    Here, in answer to my own question, are two scripts (one js one c#) that reproduce the behaviour of the standard asset DragRidgidbody.js script but on 2D sprites.

    I hope they are of help to someone else. My initial posts seemed not to generate a response so I spent the day solving the problem (that I'm sure is quite simple to the experienced).

    If anyone has suggestions or improvements (especially around the SpringJoint2D settings as conversion between the SpringJoint 3D and the 2D are not one-to-one.

    Notes: Ray / Hit test
    I used a layer mask. See the comments in the script. I set 'touchable' sprites to that layer. That lets me create non-selectedable collision objects and blend 2D and 3D collisions. So be sure to set one and check the layer mask index matches yours.
    Centre of Mass Setting Currently Disabled
    Currently 'centerOfMass' isn't reported for 2D physics like 3D Physics yet - it will be added in a future Unity release. See code comments for a URL to the info.
    2D/3D Interaction
    A useful thing for me: if the 3D DragRigidbody.js script is in the scene, a single click can drag both objects. If you do that you can see the spring settings / control feel are very different 2D snappy, 3D lazy.

    Anyone who can help convert this to multitouch - or indicate the schematic of how that could work - that would be fab. I get the principles of how I can do it. But would love to check the methodology before beginning...

    I also attach an image of the script working on a 2D sprite chain colliding with a 3D sphere on a spring (the sphere has a child Circle Collider 2D).

    C# DragRigidbody2D.cs

    Code (csharp):
    1. // Conversion of standard DragRigidbody.js to DragRigidbody2D.cs
    2. // Ian Grant v001
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class DragRigidBody2D : MonoBehaviour
    7. {
    8.  
    9. // Class Variables
    10.         public float distance = 0.2f;
    11.         public float damper = 0.5f; // damping ration in SpringJoint2D (0.0.- 1.0)
    12.         public float frequency = 8.0f;
    13.         public float drag = 1.0f; // this doesn't exist on 2D Spring...
    14.         public float angularDrag = 5.0f;
    15.         //var distance = 0.2;
    16.         public bool attachToCenterOfMass = false;
    17.         private SpringJoint2D springJoint;
    18.    
    19.  
    20. // Update
    21.         void Update ()
    22.         {
    23.    
    24.  
    25.                 if (!Input.GetMouseButtonDown (0))
    26.                         return;
    27.        
    28.                 Camera mainCamera = FindCamera ();
    29.                 int layerMask = 1 << 8;
    30.                 RaycastHit2D hit = Physics2D.Raycast (mainCamera.ScreenToWorldPoint (Input.mousePosition), Vector2.zero, Mathf.Infinity, layerMask);
    31.                 Debug.Log ("Layermask: " + LayerMask.LayerToName (8));
    32.                 // I have proxy collider objects (empty gameobjects with a 2D Collider) as a child of a 3D rigidbody - simulating collisions between 2D and 3D objects
    33.                 // I therefore set any 'touchable' object to layer 8 and use the layerMask above for all touchable items
    34.  
    35.                 if (hit.collider != null  hit.rigidbody.isKinematic == true) {
    36.                         return;
    37.                 }
    38.  
    39.                 if (hit.collider != null  hit.rigidbody.isKinematic == false) {
    40.            
    41.            
    42.                         if (!springJoint) {
    43.                                 GameObject go = new GameObject ("Rigidbody2D Dragger");
    44.                                 Rigidbody2D body = go.AddComponent ("Rigidbody2D") as Rigidbody2D;
    45.                                 springJoint = go.AddComponent ("SpringJoint2D") as SpringJoint2D;
    46.                
    47.                                 body.isKinematic = true;
    48.                         }
    49.  
    50.                         springJoint.transform.position = hit.point;
    51.  
    52.  
    53.                         if (attachToCenterOfMass) {
    54.            
    55.                                 Debug.Log ("Currently 'centerOfMass' isn't reported for 2D physics like 3D Physics - it will be added in a future release.");
    56.                                 // Currently 'centerOfMass' isn't reported for 2D physics like 3D Physics yet - it will be added in a future release.
    57.                
    58.                                 //Vector3 anchor = transform.TransformDirection(hit.rigidbody.centerOfMass) + hit.rigidbody.transform.position; in c# might be Vector2?
    59.                
    60.                                 //anchor = springJoint.transform.InverseTransformPoint(anchor);
    61.                                 //springJoint.anchor = anchor;
    62.                         } else {
    63.                
    64.                                 //springJoint.anchor = Vector3.zero;
    65.                         }
    66.  
    67.                         springJoint.distance = distance; // there is no distance in SpringJoint2D
    68.                         springJoint.dampingRatio = damper;// there is no damper in SpringJoint2D but there is a dampingRatio
    69.                         //springJoint.maxDistance = distance;  // there is no MaxDistance in the SpringJoint2D - but there is a 'distance' field
    70.                         //  see http://docs.unity3d.com/Documentation/ScriptReference/SpringJoint2D.html
    71.                         //springJoint.maxDistance = distance;
    72.                         springJoint.connectedBody = hit.rigidbody;
    73.            
    74.            
    75.                         // maybe check if the 'fraction' is normalised. See http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit2D-fraction.html
    76.                         StartCoroutine ("DragObject", hit.fraction);
    77.  
    78.  
    79.  
    80.                 } // end of hit true condition
    81.  
    82.         } // end of update
    83.  
    84.  
    85.         IEnumerator DragObject (float distance)
    86.         {  
    87.        
    88.                 float oldDrag = springJoint.connectedBody.drag;
    89.                 float oldAngularDrag = springJoint.connectedBody.angularDrag;
    90.  
    91.                 springJoint.connectedBody.drag = drag;
    92.                 springJoint.connectedBody.angularDrag = angularDrag;
    93.  
    94.                 Camera mainCamera = FindCamera ();
    95.  
    96.                 while (Input.GetMouseButton (0)) {
    97.                         Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition);
    98.                         springJoint.transform.position = ray.GetPoint (distance);
    99.                         yield return null;
    100.                 }
    101.        
    102.        
    103.        
    104.                 if (springJoint.connectedBody) {   
    105.                         springJoint.connectedBody.drag = oldDrag;
    106.                         springJoint.connectedBody.angularDrag = oldAngularDrag;
    107.                         springJoint.connectedBody = null;
    108.                 }
    109.  
    110.         }
    111.  
    112.         Camera FindCamera ()
    113.         {
    114.                 if (camera)
    115.                         return camera;
    116.                 else
    117.                         return Camera.main;
    118.         }
    119. }
    120.  
    JS DragRigidbody2D.js

    Code (csharp):
    1.  
    2. // Conversion of standard DragRigidbody.js to DragRigidbody2D.js
    3. // Ian Grant v001
    4.  
    5. var distance =0.2;
    6. var damper = 0.5; // damping ration in SpringJoint2D (0.0.- 1.0)
    7. var frequency = 8.0;
    8. var drag = 1.0; // this doesn't exist on 2D Spring...
    9. var angularDrag = 5.0;
    10. //var distance = 0.2;
    11. var attachToCenterOfMass = false;
    12.  
    13.  
    14. private var springJoint : SpringJoint2D;
    15.  
    16. function Update ()
    17. {
    18.     // Make sure the user pressed the mouse down
    19.     if (!Input.GetMouseButtonDown (0))
    20.         return;
    21.  
    22.     var mainCamera = FindCamera();
    23.     var layerMask = 1 << 8;
    24.     var hit : RaycastHit2D = Physics2D.Raycast(mainCamera.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity, layerMask);
    25.     Debug.Log("Layermask: "+LayerMask.LayerToName(8));
    26.     // I have proxy collider objects (empty gameobjects with a 2D Collider) as a child of a 3D rigidbody - simulating collisions between 2D and 3D objects
    27.     // I therefore set any 'touchable' object to layer 8 and use the layerMask above for all touchable items
    28.    
    29.     if (hit.collider != null   hit.rigidbody.isKinematic==true)
    30.         {
    31.             return;
    32.         }
    33.        
    34.     if (hit.collider != null   hit.rigidbody.isKinematic==false) {
    35.        
    36.  
    37.         if (!springJoint)
    38.         {
    39.             var go = new GameObject("Rigidbody2D Dragger");
    40.             var body : Rigidbody2D = go.AddComponent ("Rigidbody2D") as Rigidbody2D;
    41.             springJoint = go.AddComponent ("SpringJoint2D");
    42.            
    43.             body.isKinematic = true;
    44.         }
    45.        
    46.         springJoint.transform.position = hit.point;
    47.        
    48.         if (attachToCenterOfMass)
    49.         {
    50.             Debug.Log("Currently 'centerOfMass' isn't reported for 2D physics like 3D Physics - it will be added in a future release.");
    51.             // Currently 'centerOfMass' isn't reported for 2D physics like 3D Physics yet - it will be added in a future release.
    52.            
    53.             //var anchor = transform.TransformDirection(hit.rigidbody.centerOfMass) + hit.rigidbody.transform.position;
    54.            
    55.             //anchor = springJoint.transform.InverseTransformPoint(anchor);
    56.             //springJoint.anchor = anchor;
    57.         } else{
    58.        
    59.             //springJoint.anchor = Vector3.zero;
    60.            
    61.         }
    62.        
    63.         springJoint.distance = distance; // there is no distance in SpringJoint2D
    64.         springJoint.dampingRatio = damper;// there is no damper in SpringJoint2D but there is a dampingRatio
    65.         //springJoint.maxDistance = distance;  // there is no MaxDistance in the SpringJoint2D - but there is a 'distance' field
    66.                                             //  see http://docs.unity3d.com/Documentation/ScriptReference/SpringJoint2D.html
    67.         //springJoint.maxDistance = distance;
    68.         springJoint.connectedBody = hit.rigidbody;
    69.        
    70.        
    71.         // maybe check if the 'fraction' is normalised. See http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit2D-fraction.html
    72.         StartCoroutine ("DragObject", hit.fraction);
    73.        
    74.         } // end of hit true condition
    75.        
    76.     } // end of update
    77.  
    78. function DragObject (distance : float)
    79. {  
    80.  
    81.     var oldDrag = springJoint.connectedBody.drag;
    82.     var oldAngularDrag = springJoint.connectedBody.angularDrag;
    83.     springJoint.connectedBody.drag = drag;
    84.     springJoint.connectedBody.angularDrag = angularDrag;
    85.     var mainCamera = FindCamera();
    86.     while (Input.GetMouseButton (0))
    87.     {
    88.         var ray = mainCamera.ScreenPointToRay (Input.mousePosition);
    89.         springJoint.transform.position = ray.GetPoint(distance);
    90.         yield;
    91.     }
    92.    
    93.    
    94.    
    95.     if (springJoint.connectedBody)
    96.     {  
    97.         springJoint.connectedBody.drag = oldDrag;
    98.         springJoint.connectedBody.angularDrag = oldAngularDrag;
    99.         springJoint.connectedBody = null;
    100.     }
    101. }
    102.  
    103. function FindCamera ()
    104. {
    105.     if (camera)
    106.         return camera;
    107.     else
    108.         return Camera.main;
    109. }
    110.  
    $screen_2D_dragable_dragon_.png

    Kind regards,

    Ian
     
    Last edited: Nov 21, 2013
  3. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    This script works great, except it always seems to "pick up" the object on it's center point. So if you have say a hockey stick, and try to grab it by the top of the handle, it jerks to the center. I can't figure out for the life of me why it's doing this. Any one know?

    Thanks!
     
  4. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    Low and behold, I answered my own question.

    The problem was that SpringJoint2D doesn't have the ability to autoConfigureConnectedAnchor that SpringJoint does (and it's enabled by default). As a result, the connectedAnchor is always 0,0 in local space unless you specifically set it.

    After:

    Code (csharp):
    1. springJoint.connectedBody = hit.rigidbody;
    Add:

    Code (csharp):
    1.    
    2. Vector3 localPoint = transform.InverseTransformPoint (hit.point);
    3. springJoint.connectedAnchor = localPoint;
    4.  
    We have to transform the hit.point back into location space and apply that to connectedAnchor.

    That's it!
     
  5. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    I just wanted to mention that there is a public float distance and IEnumerator DragObject (float distance). You might want to change the name of distance in DragObject.

    Also, You probably don't need to do the check at line 28 since you're doing the same thing in 33.

    Thanks a lot for this script. I've used it many times now.
     
  6. Athomield3D

    Athomield3D

    Joined:
    Aug 29, 2012
    Posts:
    193
    Hi, how do I implement this script ?
     
  7. ianjgrant

    ianjgrant

    Joined:
    Mar 11, 2013
    Posts:
    28
    Hi, it is used in the same way as the DragRigidBody script in the standard assets: drag a single instance of it onto an empty game object or your main camera and then any 2D rigidbody will be dragable. Might be a good idea to make the changes slek120 and FamerJoe mention... kind regards Ian
     
  8. hafner

    hafner

    Joined:
    May 22, 2014
    Posts:
    1
    don't forget to add a BoxCollider 2D or nothing will work
     
  9. CoolWong

    CoolWong

    Joined:
    May 30, 2014
    Posts:
    1
    Hi,
    I'm new here. I try to test it with a simple sprite.
    I create a sprite. In the inspector, I have : transform, sprite renderer, Rigidbody2D, BoxCollider2D and the DragRididBody2d (script).
    When I try to drag'n'drop, in my debug, I have : Layermask: UnityEngine.Debug:Log(Object).

    I add a debug of : hit.rigidbody.isKinematic
    and it's throw a NullReferenceException :(

    Do you have the same problem ? How to resolve it ?

    Anyway, thanks a lot for this script
     
    Last edited: May 30, 2014
  10. Alec_B

    Alec_B

    Joined:
    Jun 1, 2014
    Posts:
    1
    Hey, I'm new to unity, and am looking for a script to drag a 2D Rigidbody by touch. I plan to develop the game for android. So far this script seems to be exactly what I'm looking for, but would anyone be willing to modify the script to allow for touch input instead of mouse drag and drop? Thanks, I really appreciate it!
     
  11. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    Here is my multitouch version of this script.
    I use a couple new features in Unity 4.5 (at least, I think they're new):
    rigidbody.centerOfMass and Physics2D.GetRayIntersection.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MultiDragRigidbody2D : MonoBehaviour
    5. {
    6.     public int maxTouch = 2;
    7.     [Range(0,31)]
    8.     public int layerMask = 0;
    9.     public float distance = 0.2f;
    10.     public float dampingRatio = 1;
    11.     public float frequency = 1.8f;
    12.     public float linearDrag = 1.0f;
    13.     public float angularDrag = 5.0f;
    14.     public bool centerOfMass = false;
    15.     private SpringJoint2D[] springJoints;
    16.  
    17.     void Start ()
    18.     {
    19.         springJoints = new SpringJoint2D[maxTouch];
    20.  
    21.         for (int i = 0; i < maxTouch; i++) {
    22.             GameObject go = new GameObject ("Dragger" + (i + 1));
    23.             go.transform.parent = this.transform;
    24.        
    25.             Rigidbody2D body = go.AddComponent ("Rigidbody2D") as Rigidbody2D;
    26.             springJoints [i] = go.AddComponent ("SpringJoint2D") as SpringJoint2D;
    27.             body.isKinematic = true;
    28.         }
    29.     }
    30.  
    31.     void Update ()
    32.     {
    33.         foreach (Touch touch in Input.touches) {
    34.             int Id = touch.fingerId;
    35.        
    36.             if (Id < maxTouch && touch.phase == TouchPhase.Began) {
    37.                 Camera mainCamera = FindCamera ();
    38.                 Ray ray = mainCamera.ScreenPointToRay (touch.position);
    39.                 RaycastHit2D hit = Physics2D.GetRayIntersection (ray, Mathf.Infinity, 1 << layerMask);
    40.            
    41.                 if (hit.rigidbody != null && hit.rigidbody.isKinematic == false) {
    42.                     springJoints [Id].transform.position = hit.point;
    43.                     springJoints [Id].connectedBody = hit.rigidbody;
    44.                
    45.                     if (centerOfMass)
    46.                         springJoints [Id].connectedAnchor = hit.rigidbody.centerOfMass;
    47.                     else
    48.                         springJoints [Id].connectedAnchor = hit.transform.InverseTransformPoint (hit.point);
    49.                
    50.                     float length = (hit.transform.position - mainCamera.transform.position).magnitude;
    51.                     StartCoroutine (DragObject (Id, length));
    52.                 }
    53.             }
    54.         }
    55.     }
    56.  
    57.     IEnumerator DragObject (int Id, float length)
    58.     {
    59.         float oldDrag = springJoints [Id].connectedBody.drag;
    60.         float oldAngularDrag = springJoints [Id].connectedBody.angularDrag;
    61.         springJoints [Id].distance = distance;
    62.         springJoints [Id].dampingRatio = dampingRatio;
    63.         springJoints [Id].frequency = frequency;
    64.         springJoints [Id].connectedBody.drag = linearDrag;
    65.         springJoints [Id].connectedBody.angularDrag = angularDrag;
    66.         Camera mainCamera = FindCamera ();
    67.    
    68.         while (true) {
    69.             bool touchExists = false;
    70.             foreach (Touch touch in Input.touches) {
    71.                 if (touch.fingerId == Id) {
    72.                     touchExists = true;
    73.                     Ray ray = mainCamera.ScreenPointToRay (touch.position);
    74.                     springJoints [Id].transform.position = ray.GetPoint (length);
    75.                 }
    76.             }
    77.             if (touchExists)
    78.                 yield return null;
    79.             else
    80.                 break;
    81.         }
    82.    
    83.         if (springJoints [Id].connectedBody) {
    84.             springJoints [Id].connectedBody.drag = oldDrag;
    85.             springJoints [Id].connectedBody.angularDrag = oldAngularDrag;
    86.             springJoints [Id].connectedBody = null;
    87.         }  
    88.     }
    89.  
    90.     Camera FindCamera ()
    91.     {
    92.         if (camera)
    93.             return camera;
    94.         else
    95.             return Camera.main;
    96.     }
    97. }
     
    Last edited: Jun 18, 2014
  12. Syrul

    Syrul

    Joined:
    Jan 15, 2013
    Posts:
    5
    Can't get this new script to work.. any idea?
    I have 2d sprites in my scene with 2d rigidbodies and polygon 2d colliders.
    The script is attached to main camera.
    Also, I believe the code has some error:

    Code (CSharp):
    1.     public int maxTouch = 2;
    2.     [Range(0,31)]
    3.     public int [SIZE=14px]layerMask = 0;[/SIZE]
    please assist, thanks.
     
  13. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    Remove the
    Code (CSharp):
    1. [SIZE=14px][/SIZE]
    .
    I don't know how that got in there.
    I'll edit my post.

    Make sure that your GameObject that you want to move is on default layer if layerMask = 0.
    If you don't want to use layer masking, you can change line 40 to this:
    Code (CSharp):
    1. RaycastHit2D hit = Physics2D.GetRayIntersection (ray);
    The code doesn't work with mouse.
    If anyone wants to fix that, it would be much appreciated.
     
  14. Rapskalian

    Rapskalian

    Joined:
    Jan 4, 2011
    Posts:
    45
  15. Syrul

    Syrul

    Joined:
    Jan 15, 2013
    Posts:
    5
    Hi guys,

    Thank you for your great support, this script has helped me alot.
    Another question if one of you knows the answer (relating to the MultiDrag script).
    I'm trying to do it, so when I drag my object it will slowly (physics wise) rotate back to it's original rotation point (0 degrees).

    I have tried adding the following line but it only snaps the object to rotation 0.
    Code (CSharp):
    1. springJoints [Id].transform.eulerAngles = new Vector3(0,0,0);
    Thanks,
    Syrul
     
  16. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    I don't really understand what you need but maybe this will help

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class RotateToNeutral : MonoBehaviour
    5. {
    6.     public enum Curve
    7.     {
    8.         Linear = 0,
    9.         Exponential = 1
    10.     }
    11.  
    12.     public Quaternion neutralRotation = Quaternion.identity;
    13.     public Curve curve = Curve.Linear;
    14.     public float rotateSpeed = 2;
    15.  
    16.     void FixedUpdate ()
    17.     {
    18.         if (curve == Curve.Linear)
    19.             this.rigidbody.MoveRotation (Quaternion.RotateTowards (this.rigidbody.rotation, neutralRotation, rotateSpeed));
    20.         else if (curve == Curve.Exponential)
    21.             this.rigidbody.MoveRotation (Quaternion.Slerp (this.rigidbody.rotation, neutralRotation, Time.deltaTime * rotateSpeed));
    22.     }
    23. }
    If you are using 2D, make sure to change all the rigidbody to rigidbody2D
     
  17. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    If you want to do it in one line try this
    Code (CSharp):
    1. float speed = 2;
    2. springJoints [Id].transform.rotation = Quaternion.Slerp(springJoints [Id].transform.rotation, Quaternion.identity, Time.deltaTime * speed);
     
  18. Syrul

    Syrul

    Joined:
    Jan 15, 2013
    Posts:
    5
    Hi slek120,

    Thank you for your answer.. obviously Unity has a simple answer :p
    Anyway, tried your code but it didn't work, I understood the logic was right but it didn't point the actual body.
    I've done some changes and now it works.
    Adding snippet below if anyone wants to use this.
    (Perhaps add it to the original script).

    Code (CSharp):
    1.         while (true) {
    2.             bool touchExists = false;
    3.             foreach (Touch touch in Input.touches) {
    4.                 if (touch.fingerId == Id) {
    5.                     touchExists = true;
    6.                     Ray ray = mainCamera.ScreenPointToRay (touch.position);
    7.                     springJoints [Id].transform.position = ray.GetPoint (length);
    8.                     springJoints [Id].connectedBody.transform.rotation = Quaternion.Slerp(springJoints [Id].connectedBody.transform.rotation, Quaternion.identity, Time.deltaTime * speed);
    9.                 }
    10.             }
     
  19. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    I don't understand why you need to rotate the spring joint. Can you explain?
     
  20. Mitchellhart

    Mitchellhart

    Joined:
    Jul 6, 2014
    Posts:
    3
    Im getting errors on this line:
    if (hit.collider != null hit.rigidbody.isKinematic == true)

    Error: (31,31): Error BCE0044: expecting ), found 'hit'. (BCE0044) (Assembly-UnityScript)

    Looks like a missing operator, but I'm not sure what should go here. Can someone help?
     
  21. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    The operator is &&.

    The older script doesn't use Physics2D.GetRayIntersection().
    You might want to use this:
    http://forum.unity3d.com/threads/rigidbody2d-dragable-script.212168/#post-1664297

    If you want to know the difference,
    the newer version uses a 3d ray and returns a 2d raycast hit.
    Before, the z-axis was ignored so the raycast would hit against the edge of a collider.
    Now, you can get the exact touch point (or center of mass).
     
  22. PotatoInsertion

    PotatoInsertion

    Joined:
    Mar 11, 2013
    Posts:
    23
    Hey. I'm using slek120's drag multibody script, I was hoping someone could help me add some extra functionality to it?

    I'm converting a 3D game over to a 2D one, and this scripts works perfectly so far, except I'd also like it to work when touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary as well (so you can drag your finger up to catch things or grab something if it flies towards your finger.

    I added these two conditions to line 36 above, and the dragging still works. But when I drop it, the old drag values don't transfer back, so the object just falls slowly.

    Any ideas?
     
  23. PotatoInsertion

    PotatoInsertion

    Joined:
    Mar 11, 2013
    Posts:
    23
    Have a quick fix where I add a bool. Seems it's running through the functions multiple times, so the old drag is saved as the new drag. Probably a solution of this with more finesse, but this is working so far. Added it just inside the DragObject function.


    Code (CSharp):
    1. if (!draggingObject){
    2.  
    3.             oldDrag = springJoints [Id].connectedBody.drag;
    4.             oldAngularDrag = springJoints [Id].connectedBody.angularDrag;
    5.         }
    6.  
    7.         springJoints [Id].distance = distance;
    8.         springJoints [Id].dampingRatio = dampingRatio;
    9.         springJoints [Id].frequency = frequency;
    10.         springJoints [Id].connectedBody.drag = linearDrag;
    11.         springJoints [Id].connectedBody.angularDrag = angularDrag;
    12.  
    13.         draggingObject = true;
    14.         Camera mainCamera = FindCamera ();
     
  24. slek120

    slek120

    Joined:
    Jan 6, 2014
    Posts:
    13
    So here is a method that might work.
    What I do is start a coroutine when you start a touch and continue until you let go or find an object.
    I'm not sure if this will work since I haven't tested. Tell me if this works.

    Code (CSharp):
    1.     void Update ()
    2.     {
    3.         foreach (Touch touch in Input.touches) {
    4.             int Id = touch.fingerId;
    5.          
    6.             if (Id < maxTouch && touch.phase == TouchPhase.Began) {
    7.                 StartCoroutine (LookForObject (touch, Id));
    8.             }
    9.         }
    10.     }
    11.  
    12.     IEnumerator LookForObject (Touch touch, int Id)
    13.     {
    14.         Camera mainCamera = FindCamera ();
    15.  
    16.         while (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) {
    17.             Ray ray = mainCamera.ScreenPointToRay (touch.position);
    18.             RaycastHit2D hit = Physics2D.GetRayIntersection (ray, Mathf.Infinity, 1 << layerMask);
    19.          
    20.             if (hit.rigidbody != null && hit.rigidbody.isKinematic == false) {
    21.                 springJoints [Id].transform.position = hit.point;
    22.                 springJoints [Id].connectedBody = hit.rigidbody;
    23.              
    24.                 if (centerOfMass)
    25.                     springJoints [Id].connectedAnchor = hit.rigidbody.centerOfMass;
    26.                 else
    27.                     springJoints [Id].connectedAnchor = hit.transform.InverseTransformPoint (hit.point);
    28.              
    29.                 float length = (hit.transform.position - mainCamera.transform.position).magnitude;
    30.                 StartCoroutine (DragObject (Id, length));
    31.                 break;
    32.             }
    33.  
    34.             yield return null;
    35.         }
    36.     }
     
  25. PotatoInsertion

    PotatoInsertion

    Joined:
    Mar 11, 2013
    Posts:
    23
    Hey, thanks for the reply. It kinda works, but doesn't seem as responsive as the other version, but that could just be my mind playing tricks, it's hard to tell. I'm just using Unity remote at the moment.

    Also, sometimes it still doesn't reset the old drag, etc values correctly. I've been messing around with it for a while now, but I can't isolate when or why it doesn't work. It seems to fail maybe 20/30% of the time.

    If I get a chance later I'll play around with it some more, see if I figure out why it only works some of the time.
     
  26. noise54

    noise54

    Joined:
    Dec 17, 2013
    Posts:
    3
    Slek120, Big thanks for the code! Been trying to figure this out for a month.
     
  27. pablo1b

    pablo1b

    Joined:
    Mar 14, 2015
    Posts:
    1
    Thanks everyone for sharing! Awesome code!

    I was wondering if there's an easy way to making the code work for both touch and mouse clicks (besides making two copies and replacing Input.touches with Input.GetMouseButtonDown on one).