Trouble creating a hitbox when an ability is used?

Godot Version

4.2.2

Question

Basically, I’m trying to implement a dash with a hitbox. Since the dash can be in any of 8 directions, I decided it would be easier to create the hitbox when the move is used, rather than try to do some hitbox rotation shenanigans. Here is what I’m currently using:

func perform_lightning_leap(direction):
	#Make direction octoganal
	direction = direction.normalized()
	var angle = direction.angle()
	angle = snapped(angle, PI / 4)
	direction = Vector2.RIGHT.rotated(angle)
	
	var start_pos = player.global_position
	var end_pos = start_pos + direction * dash_distance
	
	# Create a temporary hitbox for the dash
	var dash_hitbox = Area2D.new()
	var collision_shape = CollisionShape2D.new()
	var shape = RectangleShape2D.new()
	
	# Set the shape to cover the entire dash path
	shape.extents = Vector2(dash_distance / 2, 20)  # Adjust width (20) as needed
	collision_shape.shape = shape
	collision_shape.visible = true  # Make the collision shape visible for debugging
	dash_hitbox.add_child(collision_shape)
	
	# Set collision layers and masks
	dash_hitbox.collision_layer = 1 << 1  #Layer 2 (index 1)
	dash_hitbox.collision_mask = 1 << 1   #Collides with Layer 2 (index 1)
	
	# Position the hitbox between start and end positions
	dash_hitbox.global_position = (start_pos + end_pos) / 2
	dash_hitbox.rotation = direction.angle()
	
	# Add the hitbox to the scene temporarily
	add_child(dash_hitbox)
	print(collision_shape)
	
	# Connect the hitbox's area_entered signal
	dash_hitbox.connect("area_entered", Callable(self, "_on_dash_hitbox_area_entered"))
	
	var tween = create_tween()
	tween.tween_property(player, "global_position", end_pos, dash_duration)
	tween.tween_callback(func(): 
		dash_hitbox.queue_free()  # Remove the temporary hitbox
	)

When I use prints, it prints out the nodes of the area and collision shape that are being created, but I do not see the hitbox when debugging with ‘Visible Collision Shapes’ enabled. I can see all the static hitboxes that I have, but the created hitbox does not ever appear, which makes me think I’m doing something wrong when creating it. What could I possibly be missing?

I believe this should do the trick:

dash_hitbox.position = Vector2(0, 0)
add_child(dash_hitbox)

This will attach the newly created area2D to the script node, in other case it could spawn ANYWHERE in the scene and ruin everything.

Hope this helps.

Maybe setting the owner will make the collision shapes visible?

dash_hitbox.owner = self
collision_shape.owner = self

Have you confirmed if it hits anything?

The problem with that, is that then it will move with the player instead of being a stationary line. I ended up making the hitbox just be a square around the player, and having the hitbox attached to the player so it moves with them during the dash, but it’s making applying the knockback a pain in the butt. I have to write a different way of applying knockback for each of the 8 directions the player can dash…

C’est la vie I suppose.

Yeah, that helped. The issue is then that the hitbox moves with the player, so I can’t have a static line be the hitbox. I ended up making the hitbox be a square that follows the player, which added other issues, but at least those issues can be worked around.

Thanks a ton!

If you want it to be static, I suggest doing something along the lines of this:
Instead of attaching it to the player, you can attach it to the main (for example) and set its position to Vector(player.global_position.x - 10, 0), so the collider will be static and in place.
Unless this messes with signals?

What is this script attached to? I noticed a player reference, so I assumed it was not a player script? If it is attached to the player, and you want the hitbox to not be a child of the player use add_sibling then set global positions.

I’m a bit lost on why this solution would be less effort. You still even need to rotate the hitbox. What am I missing?

Granted, if you want to have position static, you’d probably need to duplicate an existing one, but that seems to be a better way to set this up than doing it via script :thinking:

I mean, even if I duplicated it that would have to be done via script. The least I can make the script do is reference an already created hitbox and then change it’s rotation based on the input based on pi/4. That’s assuming I can anchor the rotation point on one of the ends though.

I suppose it’s less effort for me because I don’t know how I would go about doing it another way, whereas I had an idea of how to do it properly the way that I mentioned.

1 Like