i’ve followed a yt tutorial on how to drag a “sprite” around, it works by detecting when the mouse enters an area and if it is keeping pressed the mouse button.
the problem is that if i place two (or more) instances in the game scene and then drag one of them around (during the “gameplay”) they both fuse together, from then on they are inseparable.
i understand that the problem comes from the “conditions” to “drag” (1. detecting if the nouse is in the area 2. detecting if the mouse button is pressed) becoming true in both the instances, but i have no idea on how to differentiate the two or marking one as “occupied” so that the other won’t stick to it. (or whatever solution there may be)
heres a screenshot of the code.
extends CharacterBody2D
var move = false
var enter = false
@warning_ignore("unused_parameter")
func _physics_process(delta: float) -> void:
var mousepos = get_global_mouse_position()
if move== true:
position = mousepos
if Input.is_action_pressed("click") and enter == true :
move = true
else:
move = false
func _on_area_2d_mouse_entered() -> void:
enter = true
func _on_area_2d_mouse_exited() -> void:
if move==false:
enter = false
sorry for my text being long-winded and for using improper terms, but it’s my first post and i’ve no idea of what i’m doing. i kindly ask for your help, thank you.
Do you have to handle selection on the CharacterBody2D nodes? If not you could have it handled by a “controller” class (e. g. the scene script), which then only allows one object to dragged at a time.
Would this work for your solution?
i think it would work, but i have not the faintest idea on how to code that (allowing only one object to be dragged at a time) , i’ll try to do some research on my own, but if you could help me a bit i would be really grateful
Is there a reason your nodes are of type CharacterBody2D? If they are just for dragging you should probably just use a Node2D.
This code (for the scene that holds the draggable objects) works by using the physics engine to find a draggable object. In order for this to work you need to put every object that can be dragged into the group “draggables”.
# This variable will hold a reference to the node we are currently dragging.
var dragged_node = null
# This stores the difference between the mouse click position and the node's origin.
var offset = Vector2.ZERO
# The _input function captures all input events like mouse clicks and movement.
func _input(event):
# Check if the event is a mouse button press.
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
if event.is_pressed():
# This is where we find which object was clicked.
# We ask the physics engine for any objects at the mouse position.
var query = PhysicsPointQueryParameters2D.new()
query.position = get_global_mouse_position()
var results = get_world_2d().direct_space_state.intersect_point(query)
# Loop through all objects found under the mouse.
for result in results:
var node = result.collider
# Check if the found object belongs to the "draggables" group.
if node.is_in_group("draggables"):
# We found a draggable node! Let's start dragging it.
dragged_node = node
# Calculate offset to prevent the node from snapping its center to the mouse.
offset = dragged_node.global_position - get_global_mouse_position()
print("Dragging started on: ", dragged_node.name)
# Break the loop since we only want to drag one object at a time.
break
else:
# The mouse button was released, so we stop dragging.
if dragged_node:
print("Dragging stopped on: ", dragged_node.name)
dragged_node = null
offset = Vector2.ZERO
# The _process function runs on every frame.
func _process(delta):
# If we are currently dragging a node...
if dragged_node != null:
# ...update its position to follow the mouse, applying the offset.
dragged_node.global_position = get_global_mouse_position() + offset
You could also use area mouse signals and let the scene know what object is being dragged. That depends on your needs.
thank you so much for all the help and the code (the comments in it are very detailed and useful) i managed to apply it and now the game works as intended! i’m truly grateful!