Search Unity

drag and throw rigidbody using mouse

Discussion in 'Scripting' started by yuriythebest, Nov 17, 2011.

  1. yuriythebest

    yuriythebest

    Joined:
    Nov 21, 2009
    Posts:
    1,125
    right, this has got me stumped. Currently I'm using DragRigidbody, however the problem there is that it doesn't follow the object instantly. DragObject.cs looked more promising
    http://www.unifycommunity.com/wiki/index.php?title=DragObject
    however there once I release the object it instantly stops. I'm running out of ideas...
     
  2. yuriythebest

    yuriythebest

    Joined:
    Nov 21, 2009
    Posts:
    1,125
    Okay in case anyone was interested here is my script that accomplishes that:
    (it's suited for throwing objects along z)
     
  3. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    That's alot of code to not do that much... The whole onmouseup and onmousedown are throwing me pretty hard. Idealy, you would capture a click, throw a ray out and see if it hit a collider attached to the object you were on. "if(hit.transform.root.transform == transform)" This way you could have a more complex object.

    You then define a drag plane and turn gravity off for the object. Don't apply force to the object, simply change the velocity to move towards the drag point. This will ideally set you up correctly. Then when you lift your mouse up, simply stop capturing and turn gravity back on. This will leave the velocity changes in tact.

    Code (csharp):
    1.  
    2. private var isDragging : boolean = false;
    3. private var dragPlane : Plane;
    4. private var moveTo : Vector3;
    5. var dragDamper : float = 5.0;
    6. var addToY : float = 5.0;
    7.  
    8. function Update(){
    9.     var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    10.     var hit : RaycastHit;
    11.     var dist : float;
    12.     if(Input.GetMouseButtonDown(0)){
    13.        
    14.         if(Physics.Raycast(ray, hit)){
    15.             if(hit.transform.root.transform == transform){
    16.                 isDragging = true;
    17.                 rigidbody.useGravity = false;
    18.                
    19.                 // defined drag plane:
    20.                 // either directional based on the camera
    21.                 //dragPlane = new Plane(-ray.direction.normalized, hit.point);
    22.                
    23.                 // or spacial based on the current position + addToY
    24.                 dragPlane = new Plane(Vector3.up, transform.position + Vector3.up * addToY);
    25.             }
    26.         }
    27.     }
    28.     if(isDragging){
    29.         var hasHit = dragPlane.Raycast(ray, dist);
    30.         if(hasHit){
    31.             moveTo = ray.GetPoint(dist);
    32.         }
    33.     }
    34.    
    35.     if(Input.GetMouseButtonUp(0)  isDragging){
    36.         isDragging = false;
    37.         rigidbody.useGravity = true;
    38.     }
    39. }
    40.  
    41. function FixedUpdate(){
    42.     if(!isDragging) return;
    43.    
    44.     var velocity = moveTo - transform.position;
    45.     rigidbody.velocity = Vector3.Lerp(rigidbody.velocity, velocity, dragDamper * Time.deltaTime);
    46. }
    47.  
    48.  
    49. @script RequireComponent(Rigidbody)
    50.  
     
  4. yuriythebest

    yuriythebest

    Joined:
    Nov 21, 2009
    Posts:
    1,125
    thanks BigMisterB! however the problem is that the object has to on the exact position of the mouse when dragged
     
  5. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    explain: "exact position of the mouse when dragged"
     
  6. yuriythebest

    yuriythebest

    Joined:
    Nov 21, 2009
    Posts:
    1,125
    right, when you drag the object (either in your code, which uses Lerp), or DragRigidBody.js, the object "follows" the position of the mouse, with a delay. My situation needs the object to be always exactly under the mouse no matter how fast it moves (like in DragObject.js in the wiki) however with the ability to throw it as well - my current script "sort of" accomplishes that but not too well
     
  7. twentyoz

    twentyoz

    Joined:
    Aug 24, 2014
    Posts:
    1
    It seem like already closed. but I modified for 2D script. And work fine as yuriythebest intent.
    Code (CSharp):
    1.  
    2.     public Camera mainCamera;
    3.     public LayerMask mask;
    4.     public float damper;
    5.     public float speed;
    6.  
    7.     RaycastHit2D hit;
    8.     Ray ray;
    9.     bool isDragging;
    10.  
    11.     void Start(){
    12.         mainCamera = MomGameManager.instance.curruntLevelCamera;
    13.     }
    14.  
    15.     Queue<Vector3> posLog;
    16.  
    17.     void Update(){
    18.         hit = Physics2D.Raycast(mainCamera.ScreenToWorldPoint(Input.mousePosition), Vector2.one, 0.01f, mask);
    19.         if(Input.GetMouseButtonDown(0)){
    20.             if(hit.collider !=null){
    21.                 if(hit.collider == collider2D)
    22.                     StartCoroutine(DragObject());
    23.             }
    24.         }
    25.     }
    26.  
    27.     IEnumerator DragObject(){
    28.         posLog = new Queue<Vector3>(5);
    29.         bool letch = true;
    30.         GameObject targetObj = this.gameObject;
    31.         while(true){
    32.  
    33.             hit = Physics2D.Raycast(mainCamera.ScreenToWorldPoint(Input.mousePosition), Vector2.one, 0.01f, mask);
    34.  
    35.             if(letch && hit.collider == collider2D)
    36.             while(Input.GetMouseButton(0)){
    37.                 rigidbody2D.velocity = Vector2.zero;
    38.  
    39.                 if(posLog.Count == 5) posLog.Dequeue();
    40.                 posLog.Enqueue(mainCamera.ScreenToWorldPoint(Input.mousePosition));
    41.  
    42.                 transform.position = mainCamera.ScreenToWorldPoint(Input.mousePosition);
    43.                 transform.position = new Vector3(transform.position.x, transform.position.y, 0);
    44.              
    45.                 letch = false;
    46.  
    47.                 yield return new WaitForEndOfFrame();
    48.             }
    49.  
    50.             if(!letch){
    51.                 Vector3[] vecs = posLog.ToArray();
    52.                 var targetVec = vecs[4] - vecs[0];
    53.                 rigidbody2D.velocity = targetVec*speed;
    54.                 break;
    55.             }
    56.             yield return null;
    57.         }
    58.     }
    I tested several times. And couldn't find problem.
    Code is quite dirty. But it will work fine.

    I hope this can help somebody struggle.