0 votes

Hey there. I'm super new to Godot and game dev in general. I am trying to find a way to rotate a a sprite when I click and drag in a circular motion and add a value to a var whenever it's moved a little bit, like you would with a valve handle or a crank. Any help would be appreciated thanks!

in Engine by (30 points)

Do you want the user having to drag by doing an arc or a straight line?

user dragging in an arc/ circle to turn the valve/crank

1 Answer

+5 votes
Best answer

I fiddled a little in the editor and this is what I came up with:

Use an Area2D with a CollisionShape2D that has the shape you want for dragging (be it a circle or a handle), make sure it is set as pickable=true, Then use a script that listens to the Area2D input_event signal so you'll know when the mouse clicks on it:

  • Sprite (crank.gd)

    • ClickArea (Area2D)

      • CollisionShape2D

After that you need further input processing and a bit of math:
crank.gd

extends Sprite


var dragging = false


func _ready():
    # Connect to the Area2D input signal so we know when the user clicks on it
    get_node("ClickArea").connect("input_event", self, "_on_area_input_event")
    set_process_input(true)


func _on_area_input_event(viewport, event, shape):
    if event.type == InputEvent.MOUSE_BUTTON:
        # Start dragging when the user presses the mouse button over the clickable area
        dragging = event.pressed


func _input(event):
    if dragging:
        if event.type == InputEvent.MOUSE_MOTION:
            var motion = event.relative_pos
            var new_pos = get_global_mouse_pos()
            var prev_pos = new_pos - motion
            var center = get_global_pos()
            # Calculate the angular motion of the crank based on the arc made with the mouse
            var angle = (prev_pos - center).angle_to(new_pos - center)
            rotate(angle)

        elif event.type == InputEvent.MOUSE_BUTTON and event.pressed == false:
            # Stop dragging when the user releases the mouse button
            dragging = false

Here is the example project: http://zylannprods.fr/dl/godot/DragRotate.zip
You probably have a more complete setup, you might adapt it for your needs :)

by (27,898 points)
selected by

Awesome I will give this a shot, Thanks!

It works.. awesome thanks!

Thanks for this!

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 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 webmaster@godotengine.org with your username.