8 way shooting on top-down shooter (no mouse interaction)

V 4.22

Hey, I’m a bit of a noob and I’m totally stumped at the moment, unfortunately I have scoured the internet for answers but everybody seems to make top-down shooters using a mouse to guide where the shots are directed and in my game the shots follow one of the 8 way directions in which the player is facing.

Currently, when the player is facing right Vector2(1,0) the bullet goes in the right direction, however, if a player is facing left Vector2(-1,0) the bullet is going right and when the player faces up, the bullet goes left Vector2(-1,0) and I can’t see where I am going wrong.

I would be really grateful if someone could help asI am pulling my hair out!. See the code below for what I have.

Player.gd

func player_movement(_delta):
	direction = Input.get_vector("left", "right", "up", "down")
	velocity = direction * speed
	look_at(global_position + velocity)

func get_last_movement():
	var last_dir = direction
	if (last_dir != Vector2(0,0)):
		shoot_direction = last_dir

var pos = global_position - position
var dir = shoot_direction
shoot.emit(pos, dir)

The above is the player script which emits a signal to the bullet manager script and shows how the shoot_direction var is set

BulletManager.gd

extends Node2D

@export var bullet_scene : PackedScene

func _on_player_shoot(pos, dir):
	var bullet = bullet_scene.instantiate()
	add_child(bullet)
	bullet.position = pos
	bullet.velocity = dir.normalized()
	print(dir)
	bullet.add_to_group("bullets")

The above is the bullet manager script which sets the position and velocity of the bullet script

Bullet.gd

extends Area2D

var speed : int = 700
var direction: Vector2
var velocity: Vector2

func _process(delta):
	translate(velocity * speed * delta)

The above is the bullet script takes the args from the signal and sets the trajectory of the bullet

When I print out the direction (Vector2) of the arg from the player script to the bullet manager it shows the correct Vector2 directions as expected but when I run the game the bullets do not.

The screenshot below shows the player facing left but the bullets shooting to the right and I can’t work this out for the life of me! Any help would be greatly appreciated, thanks.

Can you show how you assign shoot_direction?

Ah yes, I probably should have included that.

I already have a direction var but when the player is not moving the value is obviously Vector2(0,0) which is no good for a shooting direction. So, I have stored the last value which is not (0,0) which allows the player to then shoot in the direction they are facing when idle.

func player_movement(_delta):
	direction = Input.get_vector("left", "right", "up", "down")
	velocity = direction * speed
	look_at(global_position + velocity)

func get_last_movement():
	var last_dir = direction
	if (last_dir != Vector2(0,0)):
		shoot_direction = last_dir

I thought I would share how this was solved incase anybody else comes across this in the future.

The clue was actually in the look_at() method and the inheritance on child nodes.

The look_at() method propagates to the children of the node it is called on, in my case the method was being called on the CharacterBody2D node so the children where already being rotated by this method which meant that any directions sent to a child node where added to the existing position dictated by the look_at() method.

I hope this explanation makes sense to anyone that might come across this same issue.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.