I am trying to have a player running in a side scroller platformer with its arms independent from its body, so that the arms can follow the mouse (to aim).

The issue is that when the character goes to the left I use flip_h to flim it and its arm, which makes look_at() obviously not work properly. But I'm not sure how to go about fixing it since we can't just invert the rotation angle of the arm because its values do not make sense to me (they are incremented very slowly and are not comprised between 0 and 360).

GitHub project to demonstrate the issue

Player script

extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

@onready var animator = get_node("AnimatedSprite2D")
@onready var arm = get_node("Arm")

func _ready():

func _physics_process(delta):
    # Add the gravity.
    if not is_on_floor():
        velocity.y += gravity * delta

    # Handle Jump.
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # Get the input direction and handle the movement/deceleration.
    # As good practice, you should replace UI actions with custom gameplay actions.
    var direction = Input.get_axis("ui_left", "ui_right")
    if direction == 1:
        animator.flip_h = false
        arm.flip_h = false
    elif direction == -1:
        animator.flip_h = true
        arm.flip_h = true
    if direction:
        velocity.x = direction * SPEED
        velocity.x = move_toward(velocity.x, 0, SPEED)


Arm script

extends Sprite2D

# Called when the node enters the scene tree for the first time.
func _ready():
    pass # Replace with function body.

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
    # rotation = get_global_mouse_position().angle_to_point(position)
    var mouse_pos = get_global_mouse_position()
  • 2
    \$\begingroup\$ they are incremented very slowly and are not comprised between 0 and 360 Its probably a value in radians. \$\endgroup\$
    – tkausl
    Jul 27, 2023 at 17:16

1 Answer 1


flip_h is making your arm point in the "opposite" direction when you use look_at. A quick, simple solution would be to look at the "opposite" point when facing left, that is, look_at the mouse location flipped across your character:

func _process(delta):
    var mouse_pos = get_global_mouse_position()
    if flip_h:
        mouse_pos = Vector2(global_position + (global_position - mouse_pos))

The character, the mouse, and where the code should look instead

  • \$\begingroup\$ Well done! Thanks a lot :) \$\endgroup\$
    – balthazar
    Jul 28, 2023 at 16:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .