Need help with hitbox position

Hello i need help with making my hitbox flip to the direction by player is facing, because it is only working in the x(right) direction, i am a new developer and my godot version is 4.4.1 if that can help. Here’s my code and a screenshot of the hitbox:
`extends CharacterBody2D

var pitch_cooldown := 0.0
const GRAVITY = 200.0
const WALK_SPEED = 200
@export var SonicPitch = int(0)
var sonic_sound_playing = false
var coyote_time := 0.15 # Time allowed after leaving ground to still jump
var coyote_timer := 0.0

func _physics_process(delta):
pitch_cooldown -= delta
velocity.y += delta * GRAVITY

if is_on_floor():
	coyote_timer = coyote_time
else:
	coyote_timer -= delta

# Sonic Pitch Controls
if pitch_cooldown <= 0.0:
	if Input.is_physical_key_pressed(KEY_S) and Input.is_physical_key_pressed(KEY_A) and not Input.is_key_pressed(KEY_X):
		SonicPitch = 0
		pitch_cooldown = 1.0
	elif Input.is_physical_key_pressed(KEY_A) and SonicPitch < 5 and not Input.is_key_pressed(KEY_X):
		SonicPitch += 1
		pitch_cooldown = 1.0
	elif Input.is_physical_key_pressed(KEY_S) and SonicPitch > -5 and not Input.is_key_pressed(KEY_X):
		SonicPitch -= 1
		pitch_cooldown = 1.0

# Sonic Screwdriver Sound Handling
if Input.is_key_pressed(KEY_X) and coyote_timer > 0.0:
	if SonicPitch == 0.0:
		if not $Sprite2D/Sonicsounddef.is_playing():
			$Sprite2D/Sonicsounddef.play()
			sonic_sound_playing = true
	elif SonicPitch == 1.0:
		if not $Sprite2D/sonicsound1.is_playing():
			$Sprite2D/sonicsound1.play()
			sonic_sound_playing = true
	elif SonicPitch == 2.0:
		if not $Sprite2D/sonicsound2.is_playing():	
			$Sprite2D/sonicsound2.play()
			sonic_sound_playing = true
	elif SonicPitch == 3.0:
		if not $Sprite2D/sonicsound3.is_playing():
			$Sprite2D/sonicsound3.play()
			sonic_sound_playing = true
	elif SonicPitch == 4.0:
		if not $Sprite2D/sonicsound4.is_playing():
			$Sprite2D/sonicsound4.play()
			sonic_sound_playing = true
	elif SonicPitch == 5.0:
		if not $Sprite2D/sonicsound5.is_playing():
			$Sprite2D/sonicsound5.play()
			sonic_sound_playing = true
	elif SonicPitch == -1.0:
		if not $Sprite2D/"sonicsound-1".is_playing():
			$"Sprite2D/sonicsound-1".play()
			sonic_sound_playing = true
	elif SonicPitch == -2:
		if not $"Sprite2D/sonicsound-2".is_playing():
			$"Sprite2D/sonicsound-2".play()
			sonic_sound_playing = true
	elif SonicPitch == -3:
		if not $"Sprite2D/sonicsound-3".is_playing():
			$"Sprite2D/sonicsound-3".play()
			sonic_sound_playing = true
	elif SonicPitch == -4:
		if not $"Sprite2D/sonicsound-4".is_playing():
			$"Sprite2D/sonicsound-4".play()
			sonic_sound_playing = true
	elif SonicPitch == -5:
		if not $"Sprite2D/sonicsound-5".is_playing():
			$"Sprite2D/sonicsound-5".play()
			sonic_sound_playing = true

	# Stop movement when sonic sound is active
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("ScrewDriverhold")

# Stop Sonic Sound when X is released
elif not Input.is_key_pressed(KEY_X) and sonic_sound_playing:
	if SonicPitch == 0:
		$Sprite2D/Sonicsounddef.stop()
	elif SonicPitch == 1:	
		$Sprite2D/sonicsound1.stop()
	elif SonicPitch == 2:	
		$Sprite2D/sonicsound2.stop()
	elif SonicPitch == 3:	
		$Sprite2D/sonicsound3.stop()
	elif SonicPitch == 4:	
		$Sprite2D/sonicsound4.stop()
	elif SonicPitch == 5:	
		$Sprite2D/sonicsound5.stop()
	elif SonicPitch == -1:
		$"Sprite2D/sonicsound-1".stop()
	elif SonicPitch == -2:
		$"Sprite2D/sonicsound-2".stop()
	elif SonicPitch == -3:
		$"Sprite2D/sonicsound-3".stop()
	elif SonicPitch == -4:
		$"Sprite2D/sonicsound-4".stop()
	elif SonicPitch == -5:	
		$"Sprite2D/sonicsound-5".stop()
	sonic_sound_playing = false

# Player Movement and Animation
elif Input.is_action_pressed("ui_left") and Input.is_key_pressed(KEY_Z):
	if coyote_timer > 0.0:
		$Sprite2D/AnimationPlayer.play("Jump_Animation")
		await 1
		velocity.y = -GRAVITY
		velocity.x = -WALK_SPEED
	else:
		velocity.x = -WALK_SPEED

elif Input.is_action_pressed("ui_right") and Input.is_key_pressed(KEY_Z):
	if coyote_timer > 0.0:
		$Sprite2D/AnimationPlayer.play("Jump_Animation")
		await 0.5
		velocity.y = -GRAVITY
		velocity.x = WALK_SPEED
	else:
		velocity.x = WALK_SPEED

elif Input.is_action_pressed("ui_right") and Input.is_action_pressed("ui_left"):
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("Idle_Animation")

elif Input.is_action_pressed("ui_left"):
	velocity.x = -WALK_SPEED
	$Sprite2D/AnimationPlayer.play("Walk_Animation")
elif Input.is_action_pressed("ui_right"):
	velocity.x =  WALK_SPEED
	$Sprite2D/AnimationPlayer.play("Walk_Animation")
elif Input.is_key_pressed(KEY_Z):
	if coyote_timer > 0.0:
		$Sprite2D/AnimationPlayer.play("Jump_Animation")
		await 0.5
		velocity.y = -GRAVITY
	else:
		pass

# Default Idle State
else:
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("Idle_Animation")

# Flip sprite direction based on velocity
if velocity.x:
	$Sprite2D.flip_h = velocity.x < 0
	$Sprite2D/Area2D.flip_h = velocity.x < 0

# Fall Animation when not on the floor
if not is_on_floor():
	$Sprite2D/AnimationPlayer.play("Fall_Animation")

# Move player
move_and_slide()

func _on_area_2d_body_entered(body: StaticBody2D) → void:
if body.is_in_group(“Mechanic”):
if body.SonicPitch_req == SonicPitch:
if body.has_method(“Breaking”):
body.Breaking()
else:
pass
else:
pass`


(idk if the screenshot is loaded and also i’m bad with english, so sorry for grammar)

You could use flip the area’s relative position, assuming it’s collision shape is positioned at 0,0, with these two functions:

  • absf takes the absolute value (removes sign from position)
  • signf takes the sign of a value: -1 or 1
if velocity.x:
	$Sprite2D.flip_h = velocity.x < 0
	$Sprite2D/Area2D.position.x = absf($Sprite2D/Area2D.position.x) * signf(velocity.x)

Another thing i notice is comparing equality in floats, I’d highly recommend comparing by ints here, like you do with the other statements.

if SonicPitch == 0.0:
    # etc..
elif SonicPitch == 1.0:
    # etc..
elif SonicPitch == 2.0:
    # etc..
elif SonicPitch == 3.0:
    # etc..
elif SonicPitch == 4.0:
    # etc..
elif SonicPitch == 5.0:
    # etc..
elif SonicPitch == -1.0:
    # etc..

Or better yet reduce all of these checks into one string formatter

if Input.is_key_pressed(KEY_X) and coyote_timer > 0.0:
	# rename "Sonicsounddef" to "sonicsound0" for consistency
	var sonic_name: String = "Sprite2D/sonicsound%d" % SonicPitch
	var sonic_node: AudioStreamPlayer = get_node(sonic_name)
	if not sonic_node.is_playing():
		sonic_node.play()
		sonic_sound_playing = true

	# Stop movement when sonic sound is active
	velocity.x = 0
	$Sprite2D/AnimationPlayer.play("ScrewDriverhold")

elif not Input.is_key_pressed(KEY_X) and sonic_sound_playing:
	var sonic_name: String = "Sprite2D/sonicsound%d" % SonicPitch
	var sonic_node: AudioStreamPlayer = get_node(sonic_name)
	sonic_node.stop()
1 Like

Hello, so when i tried to put your code for hitbox mirroring/repositioning, it just froze the game when i moved


It says something is wrong with the absf

My bad, should be using position.x instead of the whole Vector2 position

1 Like

I’m still kind of confused with how do i fix this code, can you please give me the line of code so i can understand better what you’re saying?

The error states it cannot convert the first argument ($Sprite2D/Area2D.position) from a Vector2 (stores a X and Y component) to a float (a single decimal value). You need to give absf a single value instead of two, it’s likely you want to give it just the x component.

With just absf solved you may get another error about a Vector2 assignment, since we are assigning position (a Vector2) to a single value. Again we only want to assign to the x component. So the final line using only x components is as follows.

$Sprite2D/Area2D.position.x = absf($Sprite2D/Area2D.position.x) * signf(velocity.x)
1 Like

So maybe there can be a problem here because the Area2D is attached to CollisionShape2D, and i could’ve showed the video of how this works for me(it stopped the freezing but still the hitbox doesn’t change the position), but this website doesn’t allow new users to upload files/attachments

I’m guessing by “the Area2D is attached to CollisionShape2D” you mean the collision shape was moved instead of the Area when setting up this character. As a fix you can reset the CollisionShape2D’s position and move the Area2D to a similar place

1 Like

Oh yeah i just changed the $Sprite2D/Area2D to $Sprite2D/Area2D/CollisionShape2D, i’m a little slow. And also i’m really thank you for the help, i am genuinely amazed by how quick people here respond, and i’ll try your code optimisation idea too. So i can finally move on onto making the enemies and levels in my game, so if you like doctor who i’ll be uploading the game on itch.io

1 Like