Drag and Drop System

Godot 4.4

I’m trying to make a drag-and-drop inventory system. I want it so that when the tool is dragged to the box, the texture of the box changes. However, the tool doesn’t affect the box when it is dragged to it.

Here is what the scene tree looks like:

Here is the code for the tool:

extends Sprite2D

var dragging = false
var of = Vector2(0,0)

func _process(delta: float) -> void:
	if dragging:
		position = get_global_mouse_position() - of

func _on_tool_button_button_down() -> void:
	dragging = true
	Global.DRAGGINGTOOL = true
	of = (get_global_mouse_position() - global_position)

func _on_tool_button_button_up() -> void:
	dragging = false
	position.x = 226
	position.y = 356
	await get_tree().create_timer(5).timeout
	Global.DRAGGINGTOOL = false

Here is the code for the box:

extends Sprite2D

var box_closed = preload("res://sprites/prerendered_sprites/boxscene.png")
var box_open = preload("res://sprites/prerendered_sprites/boxbrokenscene.png")

@onready var tool_area_2d: Area2D = $"../ToolIcon/ToolButton/ToolArea2D"

func _on_area_2d_body_entered(body: Node2D) -> void:
	if body == tool_area_2d and Global.DRAGGINGTOOL == true:
		texture = box_open

Is there a better way to go about this?

Area2D seems right for the job.

If it doesn’t work, you take the debugger and look into your code to see what it does. Is _on_area_entered() not being called? Is the if condition failing?

This signal will only fire when a Body enters it. ie CharacterBody2D, StaticBody2D etc. It will not be fired when an area2D enters it.

Add a print statement to it and you will see it never fires.

func _on_area_2d_body_entered(body: Node2D) -> void:
	print("body entered: ", body)
	if body == tool_area_2d and Global.DRAGGINGTOOL == true:
		texture = box_open

Also you are tree dependent with things like this:

@onready var tool_area_2d: Area2D = $"../ToolIcon/ToolButton/ToolArea2D"

You would be better putting your tool into a group and using something like:

func _on_area_2d_body_entered(body: Node2D) -> void:
    if body.is_in_group("toolbox"):
        # handle collision with toolbox

For area detection you need this signal (there are lots of variations as well) available on another area2D:

The first of which looks something like this:


func _on_area_2d_area_entered(area: Area2D) -> void:
	pass # Replace with function body.