How do I dynamically path to nodes?

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

I am building a procedurally generated world that uses spawn points to spawn enemies and track their existence in the game world through a bool (hasSpawn = true). These spawn points use child scenes as the enemies and I want to pass information from the child to the parent in order to ‘clear’ the parent so that it is free to spawn another enemy in the future after the player kills it’s child. Since I have multiple instances of the spawn point generated procedurally, I need to find the specific path to the instance that holds the child that the player kills in order to clear that instance.

TLDR: I need to dynamically find the path from child to parent in order to change a variable.

I have tried this in multiple ways. But, this is as close as I’ve gotten so far:

var thisParent = self.get_parent();
var parentPath = self.get_path_to(thisParent); #probably incorrect usage

func _ready():
		var s = str(thisParent);
		print(s);
		var v = str(parentPath);
		print(v);

In your case, it might be better to just pass the spawn point to the children when it is spawned, so it basically knows who spawned it and can call back to it when needed. Another option is to use signals for this, as in, when the children is spawned the node register itself to a on_death signal that the children triggers when it dies.

tastyshrimp | 2020-02-15 11:06

I’m not sure why you’d need the path to change a variable, get_parent().variable = value should work fine.
Also get_path_to() gets the path from the current node to a specified node whereas get_path() gets the absolute path of the current node.

Magso | 2020-02-15 13:02

@Magso

I was trying to path to the scene because I didn’t realize that you could move up and down the scene tree.

I tried to use the get_parent() method and I’m getting: “Invalid get Index ‘animalSpawned’ (on base: ‘Node2D’)” and game freeze when the animal is spawned via the player entering a collision shape.

func _ready():
	if get_parent().animalSpawned: #also tried self.get_parent()
		print("This is true");
	else:
		print("Something is wrong");

The scene tree should look like this after game load:

spawnHolder
   -spawnPoint     #this holds the animalSpawned var
       - -animal   #this holds the _ready() function.
   -spawnPoint
       - -animal
   etc.

Not sure why this isn’t working as it seems like it should be easy.

NapalmNate | 2020-02-15 21:17

@tastyshrimp:

Not sure what you mean by “Pass the spawn point to the children” Is there a tutorial for this?

NapalmNate | 2020-02-15 21:19

To answer both of your questions.

  1. When the game is running, maybe add a debugger to the beginning of your if and change the Scene Tree from Local to Remote. That will show you how the tree actually looks like and you can see if there is any errors in that part.
  2. So everything are objects, so you can do something like.
    Spawner.gd
func spawn:
  var animal= MySuperEnemy.instance()
  animal.spawner = self
  get_parent().add_child(animal) //Add the animal as a child of the scene and not the spawner

func animalDead(animal): //The parameter is completely optional, of course.
  //do something else cool

Animal.gd

var spawner
func onDeath:
  spawner.animalDead(self)

tastyshrimp | 2020-02-15 21:37

@tastyshrimp

Thank you so very much. Switching from local to remote was the info that I needed. After being able to see the virtual tree, My error was glaring.

func _ready():
    if get_parent().get_parent().animalSpawned: #needed to go up two nodes
        print("This is true");
    else:
        print("Something is wrong");

The above code works now. I’m going to press on with this but come back later and play with your suggestion.

Thanks again!

NapalmNate | 2020-02-15 22:07