My two game objects stick together when they are dragged

Godot Version

version 4.7.1-stable

Question

I'm making a simple game, where you have a jar with a marble and you shake it the jar to make the ball move. You can take the lid on and off the jar. I added this drag and drop script for my jar:

extends Sprite2D




var of = Vector2(0,0)


# we use delta, remember process is the running program
func _process(delta):
	if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		global_position = get_global_mouse_position() - of 
	

and the same drag and drop script for the lid as well:


extends Sprite2D


# set this to false

var of = Vector2(0,0)


# we use delta, remember process is the running program
func _process(delta):
	if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		global_position = get_global_mouse_position() - of 
	
func _physics_process(delta: float) -> void:
	# Add the gravity.
	pass
#is called when an input is made

When I move the jar body around, the lid of the jar stick to it as well:

When you move the jar around, the lid would stay at the top of the jar, unless you remove the lid then it falls to the ground.

Any suggestions on how I can solve the issue?

Your scripts are attached to the Sprite2D, so only the child Sprite2D is moving, this is only the visual element and will not affect physics if that is what you are trying to do. Enabling “Visible Collision Shapes” in the debug menu at the top will help visualize this problem.

The script moves the sprite directly onto the mouse. Your sprite’s origin point is different for the jar and for the lid, but it moves both origin points directly onto the mouse. Not sure how you’d want to resolve this, or if solving some of the other problems will also solve this one.

The script also doesn’t care if you click on the jar/like, only that you’ve clicked somewhere in game. Maybe that’s intentional?

No, I wasn’t sure why the jar will move when you clicked anywhere else but the jar.

Ok so you’re checking for input in _process for both sprites, so you’re always checking for input, independently of where the click happened.

If I understood correctly, you want the lid to stay at top after the drag starts.

Notice that the lid teleports itseld when you click, so immediately after click its global position is

get_global_mouse_position() - of

If you want the lid to stay on top, you should add another offset for the lid with respect to the jar.

You can obtain this new offset from the starting global posisiont of both lid and jar, that is:

offset_from_jar = lid.global_position - jar.global_position

before the click to move all. You can compute it even immediately after the scene is created. Remember to declar it firstly outside functions, for example just below of decalration:

var of = Vector2(0,0)
var offset_from_jar := Vector2(0,0)

Beware of setting

var offset_from_jar = lid.global_position - jar.global_position

because you can’t know if, when this variable is defined, you actually have both lid and jar loaded in the scene.

If you don’t need to adjust the lid position with respect to the jar, you could also compute the offset manually.

In the end, for the lid you would have:

func _process(delta):
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
global_position = get_global_mouse_position() - of + offset_from_jar

@gertkeno Sorry for the late reply. Attaching the script to the CharacterBody2D fixed the lid and jar sticking together issue. But the clicking directly on the jar will make it jump off screen. I can still drag it around but I can’t get my cursor to be on the jar.

You Character body’s origin is probably offset from the jar’s position. Considering your not using scenes for the jar/lid the sprites are probably placed right in the middle of the scene while your CharacterBody is at it’s 0,0 origin in the corner. Try resetting the sprite’s position property, then moving the CharacterBody2D nodes where you’d like them to start.