How to spawn enemies without crashing?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By GoodDay

I’m working on a twin-stick shooter and was following some guides to create a spawning system. Right now it’s crashing every time a new enemy enters the scene via the spawner, and I was wondering what I’m not seeing.

Was getting “ERROR: (Node not found: “Player” (relative to “/root/Main/Spawner”).)”

Enemy:

extends KinematicBody2D

var health: int = 60
var velocity = Vector2()


func _physics_process(_delta):
	var Player = get_parent().get_node("Player")
	
        #This is where I'm getting the error
	position += (Player.position - position) / 35
	look_at(Player.position)     
	move_and_collide(velocity)

func handle_hit():
	health -= 20
	if health <= 0:
		queue_free()

The spawning system:

extends Node2D

onready var pos = $Position2D
var enemy = preload("res://Actors/Enemy.tscn")

func _process(delta):
	if Input.is_action_just_pressed("ui_accept"):
		spawn(enemy, pos)

func spawn(spawn_type, spawn_position):
	var new_spawn = spawn_type.instance()
	add_child(new_spawn)
	new_spawn.global_position = spawn_position.global_position

Edited to fix code formatting. Please use the {} button in future posts to format code. If it doesn’t look right in the Preview panel before submitting, it won’t be right after…

jgodfrey | 2023-01-16 21:21

What does your scene tree look like. Specifically, where are the Player, Spawner, and enemy nodes located?

jgodfrey | 2023-01-16 21:23

Not an answer to your problem however the parameters in func spawn() are superfluous.
The parameter spawn_type is being set to enemy and spawn_position is being set to pos. Both of those are class level variables and are accessible already in the function.

func spawn():
    var new_spawn = enemy.instance()
    add_child(new_spawn)
    new_spawn.global_position = pos.global_position

LeslieS | 2023-01-17 02:52

@jgodfrey
I apologize for my formatting! I’ve attached an image of my scene tree and folder. The Player and Enemy nodes are located in the “Actors” folder, and the Spawner is in the “World” folder.

@LeslieS
Thank you for pointing those out! I’ll get rid of the redundancies in the code.

GoodDay | 2023-01-17 05:59

It looks to me like you are adding spawned enemies as children of the Spawner node so your tree would end up looking like this:

Main
    Background 
    BulletManager
    Spawner
        Enemy1
        Enemy2 
    Enemy   
    Player    

If you are trying to access those newly spawned enemies their parentage (the path to the node) might become a problem. It could be what is crashing.
(Likely) Your Spawner needs access to the Main node so that you can add it as a child of that.
If so, then the adage “method down, signal up” comes into play. I would add a signal in your spawner:

signal enemy_spawned(new_enemy)      
...
func spawn():
    var new_spawn = enemy.instance()
    new_spawn.global_position = pos.global_position
    emit_signal("enemy_spawned", new_spawn)  

Connect the signal in the Main script and add the child there:

func _on_enemy_spawned(new_enemy): 
    add_child(new_enemy)   
 

With regards to the error

ERROR: (Node not found: "Player" (relative to "/root/Main/Spawner").)"   

You can see that the Player node is not a child of the Spawner node so the path to that node is invalid.

LeslieS | 2023-01-17 06:17