This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

I wrote the following code for drag and drop:

func _input(event):
if event is InputEventMouseButton:
    if event.is_pressed() && mouse_entered:
        draggingDistance = position.distance_to(get_viewport().get_mouse_position())
        dir = (get_viewport().get_mouse_position() - position).normalized()
        dragging = true
    else:
        dragging = false
elif event is InputEventMouseMotion:
    if dragging:
        position = get_viewport().get_mouse_position() - draggingDistance * dir
pass

where mouseentered and mouseexisted are mouse events.

I am having trouble stopping the object from moving with the mouse if it collides

What I tried so far:

func _process(delta):
var collided = move_and_collide(Vector2(0, 0))
if collided != null:
    dragging = false
pass

It doesn't work as I really want it to be. It's glitchy and if I moved the mouse fast it just gets to the other side of the object it collided with.

1: desired movement
works only with slow mouse movement

2: when I move the mouse fast:
enter image description here

any idea how I can do this in a clean way?

Thank you,

in Engine by (28 points)
edited by

2 Answers

+1 vote
Best answer

Thanks to @Fabián on Godot Discord. My problem was in setting the position directly and not using moveandcollide . With fast mouse movement you don't get all the mouse positions that it went over, so some position might be missing.

To fix this I modified my code to be

func _input(event):
if event is InputEventMouseButton:
    if event.is_pressed() && mouse_entered:
        draggingDistance = position.distance_to(get_viewport().get_mouse_position())
        dir = (get_viewport().get_mouse_position() - position).normalized()
        dragging = true
    else:
        dragging = false
elif event is InputEventMouseMotion:
    if dragging:
        var newPosition = get_viewport().get_mouse_position() - draggingDistance * dir
        move_and_collide(newPosition - position )
pass

I also removed the code in the _process(delta)

by (28 points)
0 votes
_input
_process

and

_physics_process

are all callback functions that the engine trigger so you write your own custom code.
You can stop executing your logic by setting them to false, ex : set_physics_process( false ) instead of dragging = false.

You could also disable collision, ex : $CollisionShape.disabled = true

Hope this helps :-)

by (895 points)

I am not looking into disabling the physics or the collision. I just want to stop the momvent when it collided. Just like if the user picks up something and if it hits something else it drops and the user has to pick it up again and move it to another way. Please check the gifs I added to the question that explains the problem.

Ok, I am no expert in 2D collisions, but now that your problem is clearer, can you use move_and_collide() ? as indicated here:

*Anything you do with move_and_slide() can also be done with move_and_collide(), it just might take a little more code.Run the scene again and try moving into the obstacle. You’ll see that the KinematicBody2D can’t penetrate the obstacle. However, try moving into the obstacle at an angle and you’ll find that the obstacle acts like glue - it feels like the body gets stuck.

This happens because there is no collision response. moveandcollide() just stops the body’s movement when a collision occurs. *

Is there a reason the collision response is not happening when I move the mouse fast, but it does happen when I move it slowly?

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.