Depends on what nodes you are using. But typically as @paintsimmon pointed out you can use the flip_h property. As for the hitbox, etc, multiply their position them by -1 on the x-axis. The key is to do nothing if there’s no input. Here’s an example I pulled from enemy code:
extends Character2D
var direction: float = 0.0
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
@onready var ranged_attack_area: Area2D = %"Ranged Attack Area"
@onready var detection_area: Area2D = %"Detection Area"
@onready var melee_attack_hit_box: Area2D = %MeleeAttackHitBox
func _physics_process(delta: float) -> void:
# .
# . Get input and update direction/velocity here
# .
move_and_slide()
if direction != 0:
_flip(direction)
direction = 0.0
func _flip(direction_float: float) -> void:
animated_sprite_2d.flip_h = direction_float < 0
_flip_area(melee_attack_hit_box, direction_float)
_flip_area(ranged_attack_area, direction_float)
_flip_area(detection_area, direction_float)
func _flip_area(area: Area2D, direction_float: float) -> void:
area.position.x = abs(area.position.x)
if direction_float < 0:
area.position.x *= -1