Bullet not going after the player

I’m using Godot 4.2.1

Hello everyone, hope you all are having a nice day. I’m currently developing a shmup(not a serious project, just making it to learn) and I’ve encountered a problem. I’m trying to make a type of bullet that is shot in the direction of the player, but it currently just flashes in and disappears. Here is my code:

extends Area2D

var speed = 300
var player = preload("res://scenes/player.tscn")
func _process(delta):
  var playerInstance = player.instantiate()
  var direction = playerInstance.position - position
  position += direction * speed * delta

func _on_area_entered(area):
  if area.is_in_group("Player"):
    queue_free()

Again, the bullet does spawn(the spawning is handled by a different script), but it disappears right after. If anyone has an idea of how to solve this, please, hit me up. I couldn’t find a tutorial or piece of documentation to help, so any ideas are welcome :slight_smile:

var player = preload("res://scenes/player.tscn")
func _process(delta):
  var playerInstance = player.instantiate()

This would make a new player every frame, it’s not added as a child so it wont be shown and I think will be freed automatically soon after. Instantiate creates a new thing from a scene.

Could use groups to find the player, though it’s best to store the result.

var playerInstance
func _ready() -> void:
  playerInstance = get_tree().get_first_node_in_group("Player")

func _process(delta: float) -> void:
  var direction = playerInstance.position - position
  position += direction * speed * delta

func _on_area_entered(area):
  if area == playerInstance:
    queue_free()
2 Likes

Hey, thanks for offering to help : )
Sadly this didn’t work : ( But I did manage to use the

 playerInstance = get_tree().get_first_node_in_group("Player")

part.
Thanks a lot : D

I’ve refined my code a bit more and arrived at this:

extends Area2D

var speed = 300
var playerInstance
var direction

func _ready():
	playerInstance = get_tree().get_first_node_in_group("Player")
func _process(delta):
	direction = (playerInstance.position - position).normalized()
	position += direction * speed * delta

func _on_area_entered(area):
	if area.is_in_group("Player"):
		queue_free()

Unfortunately, the bullet now follows the player(something I don’t want to happen) instead of just initially going in his direction
edit
Putting the “direction = (playerInstance.position - position).normalized()” part in the _ready function gave me some odd behavior, which is to say, it didn’t work

1 Like

I think it’s because every frame (_process is run every frame) the direction is updated to face the player

you should put

direction = (playerInstance.position - position).normalized()

inside _ready() :slight_smile:

2 Likes

I tried this. It didn’t work. Oddly, the bullets didn’t seem to be aiming at the player(especially when the player was to the left or top of the origin of the bullet. The bullets don’t go there at all). Even it didn’t quite work, I’d like to thank you for offering help : D

Could you post how the bullets are instantiated? _ready is called when you use add_child so maybe you need to set the bullet position before adding them as a child.

###############
## Bullet.gd ##
###############

extends Area2D

var speed = 300
var playerInstance
var direction

func _ready():
	playerInstance = get_tree().get_first_node_in_group("Player")
	# must set position before add_child, or it will be 0,0
	direction = (playerInstance.position - position).normalized()

func _process(delta):
	position += direction * speed * delta

func _on_area_entered(area):
	if area.is_in_group("Player"):
		queue_free()

###############
## Enemy.gd  ##
###############

func fire() -> void:
	var instance = projectile.instantiate()
	# set position before adding
	instance.position = self.position
	add_sibling(instance)
2 Likes

Sure!

func fire():
	var instance = projectile.instantiate()
	add_sibling(instance)
	instance.position = position

Here the position of the bullets are set to the enemy’s position(this is the enemy script)

aha! that’s the issue as described in my previous example. I will edit the example to better match your enemy script.

1 Like

Alright! If you have any doubts I’ve made a video about the issue

Yes, try applying this change with the direction set in _ready

func fire():
	var instance = projectile.instantiate()
	instance.position = position # set position before add_sibling
	add_sibling(instance)

Easy to gloss over, just a line-swap; but it won’t be able to calculate direction if the bullet thinks it’s at 0,0 when it’s is added.

2 Likes

HOLLY MOLLY, IT DID WORK. Thanks a lot : D
Now I feel kind of silly knowing it was something so basic lol