Topic was automatically imported from the old Question2Answer platform.
Asked By
CollyBlargle
I want to rotate an Area2D around its pivot according to how far it was dragged. Essentially, the rotate tool in many image editing softwares. Kind of like this. Imgur: The magic of the Internet
extends Area2D
func _input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_RIGHT:
if event.is_action_released("right_click"):
state = NONE
else:
if mouseOnMe:
get_parent().set_selected(self)
initialOrientation = rotation
#Can I use this somehow?
state = ROTATING
func _process(_delta):
if state == ROTATING:
var vector = get_global_mouse_position() - global_position
var angle = vector.angle()
rotation = angle
This works perfectly only when I select the right side of the Area2D, but when I select the left side of it, it rotates 180 degrees, and only then follows the behavior I want (Same for any other value that isn’t 0 degrees). Notice in the video I sent, the rotation happens according to the initial reference point of the first click.
did you solve your problem?
ramazan | 2022-01-05 11:05
No, my method that I have listed only works if you select the right side of the Area2D… I’m not sure how to make it rotate depending on the mouse movement and not just “face the mouse”.
This behavior is not quite similar to what I want. While this system’s rotation is dependent on the mouse’s x position, I want both the x and y values to be considered to make a “polar coordinate” rotation system, similar to how it is in many image editing softwares.
CollyBlargle | 2022-01-05 21:04
I know that it wasn’t exakt your request, but the math should be the same.
You need
the start rotation of your object = A
the angle to the start drag point = B
the angle to the current mouse drag point = C
you calculate the new rotaion of the object X by
X = C - B + A
With C - B you calculate your delta rotation while you drag and than you add the delta to A, so basicly the rotation bevor drag + the drag delta
Here is the code, i deactivted get_parent().set_selected(self) just for the example, because i got an error and didnt know what you tried to accomplish
extends Area2D
var mouseDragStartAngle = 0
func _input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_RIGHT:
if event.is_action_released("right_click"):
state = NONE
else:
if mouseOnMe:
#get_parent().set_selected(self)
initialOrientation = rotation
#Can I use this somehow?
mouseDragStartAngle = (get_global_mouse_position() - global_position).angle()
state = ROTATING
func _process(_delta):
if state == ROTATING:
var vector = get_global_mouse_position() - global_position
var mouseDragCurrentAngle = vector.angle()
rotation = (mouseDragCurrentAngle - mouseDragStartAngle) + initialOrientation
you can see i only added mouseDragStartAngle and changed the calculation of rotation
chesse | 2022-01-05 22:05
Ah! I see. I implemented A without B, and implemented B without A before, and was frustrated that they didn’t work individually. Thank you!
Hi, my solution uses local coordinates instead of global coordinates of mouse cursor → method CanvasItem.get_local_mouse_position(); it is more consistent with the rotation of an object.
In addition, I use the event InputEventMouseMotion to update the rotation of the Area2D node, instead of the _process() function.
The line get_local_mouse_position().rotated(rotation) retrieves the position vector of the mouse pointer in the local space, which must be rotated by the rotation angle of Area2D node.
extends Area2D
enum { NONE, ROTATING}
var state = NONE
var mouse_on_me: bool = false
var initial_mouse_pos: Vector2
var initial_angle: float
func _input(event: InputEvent) -> void:
if event is InputEventMouseButton:
if event.button_index == BUTTON_RIGHT:
if event.pressed: # press button
if mouse_on_me:
initial_angle = rotation
initial_mouse_pos = get_local_mouse_position().rotated(rotation)
state = ROTATING
else: # release button
state = NONE
if event is InputEventMouseMotion:
if state == ROTATING:
var current_mouse_pos: Vector2 = get_local_mouse_position().rotated(rotation)
var angle = initial_mouse_pos.angle_to(current_mouse_pos)
rotation = angle + initial_angle
func _on_Area2D_mouse_entered() -> void:
mouse_on_me = true
func _on_Area2D_mouse_exited() -> void:
mouse_on_me = false