From my understanding you want the sword to be a certain distance away from the player, and when the mouse moves, you would like to to move around in a circle around the player.
look_at can achieve this, but it is better for 3D games as it applies the rotation as well. The maths involved in 2D is trivial.
For the weapon, you can do the following.
- get the normalised vector of the mouse away from the node the sword is attached to
- multiply it by a set distance
- set the sword’s
global_positionto the result
Because the normalised vector will never have a magnitude greater than 1, it ends up effectively forming a circle. This blog post explains more if you’re curious about the maths: Introduction to vector math for game developers | GDQuest or Gabor Makes Games
You can attach the following script to your sword node to do this (make sure to select the node_to_track as your player):
extends Node2D
@export var node_to_track:Node2D
@export var distance_away_from_node_to_track:float = 100
func _process(delta: float) -> void:
var tracked_node_to_mouse_position = get_global_mouse_position() - node_to_track.global_position
if tracked_node_to_mouse_position.length_squared() > 0:
var mouse_direction = tracked_node_to_mouse_position.normalized()
global_position = node_to_track.global_position + (mouse_direction * distance_away_from_node_to_track)
The code above will do something like this:

Node tree (Sub contains script):
Main is 100m×100m, and Sub is 50m×50m
If you want to improve the ‘feel’, look into interpolating the positions using e.g. slerp or lerp. This would add a bit of a delay to the movement but it could give some nice weight to the sword.
