Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How to drag 2D objects around the screen?

Discussion in '2D' started by JamieJamJams, Sep 27, 2015.

  1. JamieJamJams

    JamieJamJams

    Joined:
    Apr 7, 2015
    Posts:
    8
    Hi,

    I have a 20 small elements, which the player needs to click, drag, and move to another position and stay where it is when the player releases the mouse click. I'm developing for iPad, so it would be best if the user could click and drag multiple elements at a time. It would also be great if the elements wouldn't bump into each other. They need to freely slide around.

    I've tried searching for solutions, watched all the Youtube tutorials that come up with relevant searches, but each one I find just isn't quite the same as what I'm doing, so they don't work. I'm working with 2D elements only.

    How can I make this work?

    Thank you!
     
  2. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    You would have to detect if an element has been clicked, for instance with raycast or overlapcircle. Then, until there is a mouseup event, the position of the element that had been selected in the previous step should be set to the position of the mouse.
    At least, that's how I'm doing it.
     
  3. JamieJamJams

    JamieJamJams

    Joined:
    Apr 7, 2015
    Posts:
    8
    Do you have some example code? I'm quite new to this :/
     
  4. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    Something like this could work to get the element:
    Code (CSharp):
    1. if(Input.GetMouseButtonDown(0))
    2.         {
    3.             var hits = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.up, 0.5f);
    4.             for(int i = 0; i < hits.Length; i++)
    5.             {
    6.                 if(hits[i].collider.gameObject != null)
    7.                 {
    8.                     var e = hits[i].collider.gameObject.GetComponent<Element>();
    9.                     if(e != null)
    10.                     {
    11.                         StartCoroutine(MoveElement(e));
    12.                         break;
    13.                     }
    14.                 }
    15.             }
    16.         }
    Then something like this for moving:
    Code (CSharp):
    1. private IEnumerator MoveElement(Element e)
    2. {
    3. while(true)
    4.         {
    5.             yield return null;
    6.             e.transform.position = Input.mousePosition;          
    7.             if(Input.GetMouseButtonUp(0))
    8.                 break;
    9.         }      
    10. }
    But I'm sure if you spend some time playing around with it, you will find a solution that works better for your specific needs.
     
  5. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    There's already specific drag support, and the usual code you'll find for that looks like this:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(BoxCollider2D))]
    5. public class BoxDragger : MonoBehaviour
    6. {
    7.     private Vector3 loc;
    8.     private Vector3 offset;
    9.  
    10.     void OnMouseDown()
    11.     {
    12.         offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, loc.z));
    13.     }
    14.  
    15.  
    16.     void OnMouseDrag()
    17.     {
    18.         Vector3 screenpos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, loc.z);
    19.         Vector3 objpos = Camera.main.ScreenToWorldPoint(screenpos) + offset;
    20.         transform.position = objpos;
    21.     }
    22. }
    (Similar exists for touch, I believe)

    But that still needs something extra to stop objects when they collide, which the above code doesn't. If anybody knows, more people would love to know :)
     
  6. JamieJamJams

    JamieJamJams

    Joined:
    Apr 7, 2015
    Posts:
    8
    Rostam24 - Maybe I'm just not experienced enough to know what to do/where to put your code example, but I tried several different things and got errors all over the place. I couldn't get it to compile. But I would love to try to get this to work. It looks like it solves the collider issue?

    orb - This worked like a charm! I love it, thank you! This will work great! Not too worried about the lack of colliders, that will just be bonus points if I can get something working in the future I guess. :)
     
    Last edited: Sep 27, 2015
  7. JamieJamJams

    JamieJamJams

    Joined:
    Apr 7, 2015
    Posts:
    8
    orb - I just solved the collider issue! I just put a box collider 2D on the elements. Then I put a Rigid body 2D, then I set the Gravity scale to 0. This works very nicely. It makes it possible to bump the elements into other ones and even move the ones which get hit.
     
  8. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    Yep, got the same results, but it would be even nicer if they could bump & stop rather than push other things around :)
     
  9. JamieJamJams

    JamieJamJams

    Joined:
    Apr 7, 2015
    Posts:
    8
    If you find a solution, let me know! I'll keep fiddling too.
     
  10. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    You want it to stop completely? Would it help if all elements would be kinematic (except the one being dragged)?
     
  11. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    Nope, kinematic doesn't help. I've tried all sorts of combinations, and either they drag through each other, or they push each other.
     
  12. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    Heh, well I guess it requires some more scripting :)
     
  13. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    Yep, I think doing something more advanced than pushing things around probably needs a hefty script that checks directions and colliders. I thought it would be automatically handled by the engine with proper colliders :/