How to drag 2D objects around the screen?

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!

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.

Do you have some example code? I’m quite new to this :confused:

Something like this could work to get the element:

if(Input.GetMouseButtonDown(0))
        {
            var hits = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.up, 0.5f);
            for(int i = 0; i < hits.Length; i++)
            {
                if(hits[i].collider.gameObject != null)
                {
                    var e = hits[i].collider.gameObject.GetComponent<Element>();
                    if(e != null)
                    {
                        StartCoroutine(MoveElement(e));
                        break;
                    }
                }
            }
        }

Then something like this for moving:

private IEnumerator MoveElement(Element e)
{
while(true)
        {
            yield return null;
            e.transform.position = Input.mousePosition;           
            if(Input.GetMouseButtonUp(0))
                break;
        }       
}

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.

There’s already specific drag support, and the usual code you’ll find for that looks like this:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(BoxCollider2D))]
public class BoxDragger : MonoBehaviour
{
    private Vector3 loc;
    private Vector3 offset;

    void OnMouseDown()
    {
        offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, loc.z));
    }


    void OnMouseDrag()
    {
        Vector3 screenpos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, loc.z);
        Vector3 objpos = Camera.main.ScreenToWorldPoint(screenpos) + offset;
        transform.position = objpos;
    }
}

(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 :slight_smile:

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. :slight_smile:

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.

Yep, got the same results, but it would be even nicer if they could bump & stop rather than push other things around :slight_smile:

If you find a solution, let me know! I’ll keep fiddling too.

You want it to stop completely? Would it help if all elements would be kinematic (except the one being dragged)?

Nope, kinematic doesn’t help. I’ve tried all sorts of combinations, and either they drag through each other, or they push each other.

Heh, well I guess it requires some more scripting :slight_smile:

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 :confused: