Problems dragging and dropping an object

Godot Version

4.2

Question

I know this might be a beginner question and I did it already in another game, but this time it is not working… I can’t figure out, what I’m missing…

My current game is a Yahtzee-clone. I have a “die”-class and 5 instances of it. In my game there are 2 areas: one for the dice to keep, the other for the dice to re-roll. I want to pick a die and drag and drop it from one area to the other.

The die is a StaticBody2D with an AnimatedSprite, a Timer and an Area2D with a rectangle as CollisionShape2D. Class_name “Die”.

var selected: bool

is used to check if the die is currently selected. At the start of the game it is not selected.

This is what I’m using to drag and drop it:

> func _physics_process(delta):
>      if selected:
>           global_position = lerp(global_position, get_global_mouse_position(), 25 * delta)

Now the problems start.
This function is used to deselect the die:

> func _input(event):
>      if event is InputEventMouseButton:
>           if event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
>                selected = false
>                print("selected = false")

Problem: all 5 instances print “selected false”

This should work, but I get no print:

> func _on_area_2d_input_event(viewport, event, shape_idx):
>      if event is InputEventMouseButton and event.pressed:
>           print("Mouse click")
>           selected = true
>      if Input.is_action_pressed("click"):
>           print("click")
>           selected = true

“click” is defined in project settings as left mouse click.

Also these function don’t show print:

> func _on_area_2d_mouse_entered():
>      print("Mouse entered " + str(id))
> 
> func _on_area_2d_mouse_exited():
>      print("Mouse left " + str(id))

@export var id:int
is the variable to give each die a unique id.

Pickable is set to true.

If I move

> if event is InputEventMouseButton and event.pressed:
>      print("Mouse click")
>      selected = true

to _input(event), all 5 instances are selected and can be dragged and dropped. But I only want the instance which was clicked to be dragged and dropped.

I’m missing something, but what? Hope that the forum can help me out!
Thanks a lot for looking into this!

Would you please consider posting code preformatted?
It allows others to check on indentation!

var maybe = like

func this_preformat() -> void:
      pass

Where is that located? Inside “Die” class?
Just by reading looks like the Dies themselves don’t know who is being selected/deselected so they all behave the same.

And this confirms it.

A good approach is a Singleton/Autoload which in theory should manage which die is being selected by passing values trough signals.
The die selected should then call on the Singleton and pass “self” as a reference.
Then, the die should connect the singleton to itself (the die), compare if the previously “self” value is the same as the die and if it is, then behave.
Same behaviour when deselected.

Sorry, I used “Blockquote” instead of “Preformatted text”, that’s why the code lost its whitespaces…

Yes, everything is inside the Die-class.

Ok, I will check the singleton solution, but I’m pretty sure that I didn’t use it in that other game where drag and drop already worked. But there I created all instances via script, not in the editor. Thanks for the quick answer anyway.

It’s not working as expected, as still all 5 instances get selected when I click on any die.

I’ve got now a globals.gd - as “Globals” in autoload.

var current_die: Die

In die.gd the _input function was changed to:

func _input(event):
	if event is InputEventMouseButton and event.pressed:
		print("Mouse click - id: " + str(id))
		Globals.current_die = self
		selected = true
	if event is InputEventMouseButton and Globals.current_die == self:
		if event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
			selected = false
			Globals.current_die = null
			print("selected = false, id: " + str(id))

De-select works, but the select part prints for all 5 instances. So, I can always and only drag and drop die[0], even if it was moved to the other area and I want to grap another die. Strange, but why is the on_area_input_event() not working? That could resolve my problem…

func _on_area_2d_input_event(viewport, event, shape_idx):
	print("Mouse entered " + str(id))

Debug messages:

Mouse click - id: 4
Mouse click - id: 3
Mouse click - id: 2
Mouse click - id: 1
Mouse click - id: 0
selected = false, id: 0

UPDATE:

As I already mentioned, the function that should be used to identify the object being clicked on (and dragged and dropped) is
on_area_2d_input_event(viewport, event, shape_idx)
The die class is working correctly with these functions:

func _input(event):
	if event is InputEventMouseButton and Globals.current_die == self:
		if event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
			selected = false
			Globals.current_die = null
			print("selected = false, id: " + str(id))


func _on_area_2d_input_event(viewport, event, shape_idx):
	print("Mouse entered " + str(id))
	if event is InputEventMouseButton and event.pressed:
		print("Mouse click - id: " + str(id))
		Globals.current_die = self
		selected = true

The problem was that in the game scene they were drawn on a panel. I found this article which gave me the idea:

I’m now redesigning my game layout, but for now I close this topic, because I found the cause and why it worked in my other game, but not in my current dice game.
Hope that this helps others when experiencing the same problem.