Dragging a 2D sprite with touch

Hi. I would like a red circle to be moved when the player touches it, as in a touch on an iPhone. and then drags the red circle somewhere. I would like the red circle to go wherever the user’s finger goes. I am still fairly new to Unity so, I have no clue how to do this. Would anyone mind helping me out? Thanks!

There are many ways to achieve this, but I recommend the EventSystems DragHandler:

  1. Make sure you create an EventSystem component in your hierarchy.
  2. Add a Physics 2D Raycaster component to your Main Camera.
  3. Write a script that implements IBeginDragHandler, IDragHandler and IEndDragHandler.
  4. Add the script to the 2D sprite. Add a 2D Collider as well.

Here is a demo script how it could look. Be aware that the logic in this one might not fit, what you’re doing:

using UnityEngine;
using UnityEngine.EventSystems;

public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
	public static GameObject DraggedInstance;

	Vector3 _startPosition;
	Vector3 _offsetToMouse;
	float _zDistanceToCamera;

	#region Interface Implementations

	public void OnBeginDrag (PointerEventData eventData)
	{
		DraggedInstance = gameObject;
		_startPosition = transform.position;
		_zDistanceToCamera = Mathf.Abs (_startPosition.z - Camera.main.transform.position.z);

		_offsetToMouse = _startPosition - Camera.main.ScreenToWorldPoint (
			new Vector3 (Input.mousePosition.x, Input.mousePosition.y, _zDistanceToCamera)
		);
	}

	public void OnDrag (PointerEventData eventData)
	{
		if(Input.touchCount > 1)
			return;

		transform.position = Camera.main.ScreenToWorldPoint (
			new Vector3 (Input.mousePosition.x, Input.mousePosition.y, _zDistanceToCamera)
			) + _offsetToMouse;
	}

	public void OnEndDrag (PointerEventData eventData)
	{
		DraggedInstance = null;
		_offsetToMouse = Vector3.zero;
	}

	#endregion
}

There are other ways, like raycasting from the camera into the scene and figuring out what was hit, but honestly I think Unity has a pretty good built-in solution which is much less error prone once you get it working.

Expanding a little on @chrismkhill. The issue with his implementation was if you moved the mouse too fast, you’d lose the sprite

The following would fix that.

    Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    bool overSprite = GetComponent<SpriteRenderer>().bounds.Contains(mousePosition);
    beingDragged = beingDragged && Input.GetButton("Fire1");
    if (overSprite)
    {
        //If we've pressed down on the mouse (or touched on the iphone)
        if (Input.GetButton("Fire1"))
        {
            beingDragged = true;
        }
    }

    if (beingDragged) {
        //Set the position to the mouse position
        transform.position = new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
                                         Camera.main.ScreenToWorldPoint(Input.mousePosition).y,
                                         0.0f);
    }

Hey there,

If you create a script with this code on a sprite, you should get what you want.

// Update is called once per frame
void Update () 
{

//Gets the world position of the mouse on the screen		
Vector2 mousePosition = Camera.main.ScreenToWorldPoint( Input.mousePosition );

//Checks whether the mouse is over the sprite
bool overSprite = this.GetComponent<SpriteRenderer>().bounds.Contains( mousePosition );
	
	//If it's over the sprite
	if (overSprite)
	{
            //If we've pressed down on the mouse (or touched on the iphone)
		if (Input.GetButton("Fire1"))
		{
                    //Set the position to the mouse position
			this.transform.position = new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
				                         	   Camera.main.ScreenToWorldPoint(Input.mousePosition).y,
				                           	   0.0f);
		}
	}
		

		
}