How to Implement Drag-and-Drop Functionality with Unity’s (New) Input System

joshua wiscaver
4 min readJul 29, 2024

--

In this tutorial, we’ll walk through setting up drag-and-drop functionality in Unity using the new Input System.

Step 1: Set Up the New Input System

Install the New Input System:

  • Open the Unity Package Manager (Window > Package Manager).
    Search for “Input System” and install it.
  • Enable the new input backends if prompted, and restart the editor if necessary.

Create Input Actions

  • Create a new Input Actions asset (Right-click in the Project window > Create > Input Actions) and name it PlayerInputActions.
  • Double-click the PlayerInputActions asset to open the Input Actions window.

Define Action Maps and Actions

  • Create a new Action Map and name it Player.
  • Add an action called Click of type Button and bind it to <Mouse>/leftButton.
  • Add another action called Point of type Value and bind it to <Pointer>/position.

Generate C# Class

  • In the Input Actions window, click the “Generate C# Class” button at the top right or from the Inspector.
  • Save the generated script with a meaningful name like PlayerInputActions.cs.

Step 2: Implement Drag-and-Drop Logic

Create a New C# Script

  • Create a new script called DragAndDropHandler.cs and attach it to an empty GameObject in your scene.

Implement the Drag-and-Drop Logic

Open the DragAndDropHandler.cs script and copy/paste the following:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class DragAndDropHandler : MonoBehaviour
{
private PlayerInputActions inputActions;
private Camera mainCamera;

private bool isDragging = false;
private GameObject selectedObject;
private Vector3 offset;

private void Awake()
{
inputActions = new PlayerInputActions();
mainCamera = Camera.main;
}

private void OnEnable()
{
inputActions.Player.Click.performed += OnClickPerformed;
inputActions.Player.Click.canceled += OnClickCanceled;
inputActions.Player.Point.performed += OnPointPerformed;
inputActions.Enable();
}

private void OnDisable()
{
inputActions.Player.Click.performed -= OnClickPerformed;
inputActions.Player.Click.canceled -= OnClickCanceled;
inputActions.Player.Point.performed -= OnPointPerformed;
inputActions.Disable();
}

private void OnClickPerformed(InputAction.CallbackContext context)
{
Debug.Log("Click performed");
Vector2 mousePosition = inputActions.Player.Point.ReadValue<Vector2>();
Debug.Log("Mouse Position: " + mousePosition);

Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, -mainCamera.transform.position.z));
worldPosition.z = 0;
Debug.Log("World Position: " + worldPosition);

Collider2D hitCollider = Physics2D.OverlapPoint(worldPosition);
if (hitCollider != null)
{
Debug.Log("Hit object: " + hitCollider.gameObject.name);
if (hitCollider.gameObject.CompareTag("Draggable"))
{
Debug.Log("Draggable object hit: " + hitCollider.gameObject.name);
isDragging = true;
selectedObject = hitCollider.gameObject;
offset = selectedObject.transform.position - worldPosition;
}
}
else
{
Debug.Log("No collider hit");
}
}

private void OnClickCanceled(InputAction.CallbackContext context)
{
Debug.Log("Click canceled");
isDragging = false;
selectedObject = null;
}

private void OnPointPerformed(InputAction.CallbackContext context)
{
if (isDragging && selectedObject != null)
{
Debug.Log("Dragging object: " + selectedObject.name);
Vector2 mousePosition = context.ReadValue<Vector2>();
Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, -mainCamera.transform.position.z)) + offset;
worldPosition.z = 0;
selectedObject.transform.position = worldPosition;
}
}
}

Step 3: Set up the Draggable Objects

Create the Draggable tag

  • Create a new tag and name it Draggable.
  • Ensure all objects you want to be draggable are tagged with the Draggable tag. Select each draggable Game Object, go to the Inspector, and set its Tag to Draggable.

Add Physics Component

  • Ensure that the draggable GameObjects have a Collider2D component (e.g., BoxCollider2D) attached so that they can be detected by the Raycast.

Step 4: Test the Implementation

  • Save all your scripts and scenes.
  • Enter Play mode and test the drag-and-drop functionality by clicking and dragging the GameObjects.
  • Watch the console logs for any debug output to verify that the correct positions and hits are detected.

Conclusion

You now have a basic drag-and-drop system for GameObjects using Unity’s new Input System.

--

--