Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | swenner |
What I want to achieve:
- Drag and drop in 2d space moves the Node2D
- Drag from the control node to 2d space should create a new Node2D
- Drag from the control to a control node should do nothing
- Drag from 2d space to the control node should delete the Node2D
I managed to implement 1, 2 and 3 with the signal based approach below, but how do I do 4? I tried to use “can_drop_data” / “drop_data” but could not get it to work either.
Project structure
- world (Node2d)
– 2DThingy (Area2d with sprite and collision)
– Menu (ColorRect)
world.gd
extends Node2D
var held_object = null
func _ready():
for node in get_tree().get_nodes_in_group("pickable"):
node.connect("clicked", self, "_on_pickable_clicked")
func _on_pickable_clicked(object):
if !held_object:
held_object = object
held_object.pickup()
func _unhandled_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
if held_object and !event.pressed:
held_object.drop()
held_object = null
func _on_Menu_sprite_pickup(sprite):
if !held_object:
print("create sprite")
held_object = sprite
add_child(sprite)
sprite.pickup()
func _on_Menu_sprite_drop_scene():
if held_object:
print("drop sprite in scene")
held_object.drop()
held_object.connect("clicked", self, "_on_pickable_clicked")
held_object = null
func _on_Menu_sprite_drop_menu():
if held_object:
print("drop sprite in menu")
remove_child(held_object)
held_object = null
2DThingy.gd
extends Area2D
signal clicked
var is_held = false
func _ready():
pass
func _physics_process(delta):
if is_held:
global_transform.origin = get_global_mouse_position()
func _input_event(viewport, event, shape_idx):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.pressed:
emit_signal("clicked", self)
func pickup():
if is_held:
return
is_held = true
set_process_input(false)
func drop():
assert(is_held)
is_held = false
set_process_input(true)
Menu.gd
extends ColorRect
const Thingy2D = preload("res://2DThingy.tscn")
signal sprite_pickup(sprite)
signal sprite_drop_scene()
signal sprite_drop_menu()
func _ready():
connect("gui_input", self, "_on_gui_input")
func _on_gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
if event.pressed:
var thingy = Thingy2D.instance()
thingy.global_position = get_global_mouse_position()
emit_signal("sprite_pickup", thingy)
elif !event.pressed:
var mouse_pos = get_global_mouse_position()
# workaround for https://github.com/godotengine/godot/issues/20881
if get_rect().has_point(mouse_pos):
emit_signal("sprite_drop_menu")
else:
emit_signal("sprite_drop_scene")