Godot Version: 4.4.1 stable
Hello to all!
My name is Thomas and I am new to Godot and to these forums. I am currently working on a simple horizontal Shoot’Em Up. One of my playable “characters” is a Polygon2D in the shape of a triangle (as a child of a CharacterBody2D). I would like to make this triangle shoot projectiles from its three corner points while having it rotating around its center (rotation happens automatically, shooting via input event). I figured most of this out through tutorials and a bit of trial and error. Unfortunately I got stuck trying to get positional information about the triangles vertices while it is rotating, which I think I will need to make the projectiles spawn at the correct location.
This is the part of my code so far:
func _ready() -> void:
# Setting the triangles offset to its center point
triangle_center = get_triangle_center()
offset_vector = Vector2.ZERO - triangle_center
$Polygon2D.offset = offset_vector
func _process(delta: float) -> void:
$Polygon2D.rotation += rotation_speed * delta
var corners = $Polygon2D.get_polygon()
corner_one = to_global(corners[0])
print(corner_one)
And this is the method I used to determine the triangles center:
func get_triangle_center() -> Vector2:
var triangle_polygon = $Polygon2D.get_polygon()
var vertex_one = triangle_polygon[0]
var vertex_two = triangle_polygon[1]
var vertex_three = triangle_polygon[2]
var center_x = (vertex_one.x + vertex_two.x + vertex_three.x) / 3.0
var center_y = (vertex_one.y + vertex_two.y + vertex_three.y) / 3.0
return to_global(Vector2(center_x, center_y))
print(corner_one)
… gives me (64.0, 192.0), but this never changes even though the triangle is spinning.
Help is much appreciated, thanks a lot!
You could probably simplify this, but you’ve got a center position, three vertices and a rotation. You can do something like this:
func calc_shot_emission_point(center: Vector2, vert: Vector2, ang: float) -> Vector2:
return (vert - center).rotated(ang)
Basically, we subtract the center from the poly vertex to give us the vector from the center to the corner. We then rotate that by the global angle of the object.
Once you have that, it’s also the direction you want your shots to go, so you can do this:
for i in 3:
var vert: Vector2 = triangle_polygon[i]
var gun: Vector2 = calc_shot_emission_point(triangle_center, vert, rotation)
var vec: Vector2 = gun.normalized() * SHOT_SPEED
# create a bullet at `vert` with velocity vector `vec`
Normalizing makes a vector be of length 1.0 without changing its direction, so we use the normalize to scale the vector to a length of 1.0 and then multiply by speed to get it going in the correct direction at the desired speed.
Thank you very much for your help! I implemented your shot_emission_point calculation into my shoot function. It worked perfectly fine except for a little offset from the vertices actual positions. I was able to fix that by adding a new bullet_offset vector. My code now looks like this:
Finding the triangles center to set the correct offset, so the triangle can spin around its center:
triangle_center = get_triangle_center()
offset_vector = Vector2.ZERO - triangle_center
$Polygon2D.offset = offset_vector
Adding rotation:
$Polygon2D.rotation += rotation_speed * delta
Adding shooting functionality:
var triangle_polygon = $Polygon2D.get_polygon()
for each_corner in triangle_polygon.size():
var corner_position = (triangle_polygon[each_corner])
var shot_direction = (corner_position - triangle_center).rotated($Polygon2D.rotation)
var bullet = bullet_scene.instantiate() as RigidBody2D
var bullet_offset = Vector2.ZERO - corner_position
bullet.global_position = to_global(corner_position) + bullet_offset
bullet.rotation = $Polygon2D.rotation
bullet.apply_impulse(shot_direction.normalized() * bullet_speed)
get_parent().add_child(bullet)
The final result looks like this, which is exactly what I was going for:
Thanks again for your help, much appreciated!
1 Like