How to get nodes that have different names in script?

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

I’m making a 2d platformer that has a player and some different enemies. Now I’m trying to add a knockback effect to the player whenever he gets hit. To do this I need to know the enemy’s position.x so that if the player get hit from the right of the enemy, then he should have a knockback to the left, and vice versa.

The problem is that I have different types of enemies in my main scene and they have different node names. For example one is named “Skeleton” and the other is named “Goblin”. So I can’t really write:

var enemy = get_parent().get_node(“Skeleton”)

Because then I would only get the skeleton and not the other enemies.

How can I reference these in my script even though they have different names from each other?

I tried to do this using an enum that I made in the enemy script which lets me choose what type of enemy I want. It looks like this:

export(String, "Skeleton", "Goblin") var Enemy_Type

And then I added this in my player script:

onready var enemyScript = "res://Scripts/Enemy.gd"
onready var enemy = get_parent().get_node(str(enemyScript.Enemy_Type))

I really thought that this would work but instead I got an error message saying:

Invalid get index ‘Enemy_Type’ (on base: ‘String’)

If anyone could tell me what I did wrong in my script or give me another method to do this then that would be highly appreciated.

:bust_in_silhouette: Reply From: djmick

I would just put all of the enemies into a group called “enemies”. Then I would add an area2d to the player with a collision shape slightly larger than it’s normal one, and attach the on body entered method to the player script and check if the body was in the enemy group.

func _on_hitbox_body_entered(body):
     if body.is_in_group("enemies"):
          #add the knockback

You can also get the enemies position, because the body variable gives you access to all of the enemies functions and variables.

 func _on_hitbox_body_entered(body):
         if body.is_in_group("enemies"):
              var enemy_position = body.global_position

I hope this helps!

What do you mean when you say “Put all enemies in a group called enemies”? Do you mean creating a new empty node and dragging all of my enemies in there? I did that and added this to my player script.

func _on_Hurtbox_body_entered(body):
   if body.is_in_group("Enemies"):
	  var enemy_position = body.global_position
	  is_hit = true
	  $AnimatedSprite.play("Player_Hit")
	  if enemy_position.x > self.position.x:
	  	knockback = Vector2.RIGHT * knockbackPower
	  elif enemy_position.x < self.position.x:
		knockback = Vector2.LEFT * knockbackPower
	  yield($AnimatedSprite, "animation_finished")
	  is_hit = false

But now the knockback isn’t applied at all. Any idea what i’m doing wrong?

LyguN | 2021-02-04 09:49

No, you don’t need to add them to a node2d. Every node in Godot can be put into a group. When you click on a node, on the top of the inspector tab where it says inspector, you can click on the “node” tab, which opens two more tabs; one is the signals, and the other is the groups. You could just type “enemies” for each of them’s groups, and they would be in the group enemies. Alternatively, you could do it in code in the ready function of the enemies:

add_to_group("enemies")

You should look into groups, they’re very helpful. I hope this helps, if not, I would be happy to answer any more questions.

djmick | 2021-02-04 13:45

It works! Thank you very much. Did not even know about the groups feature. Will definetly look into it more.

LyguN | 2021-02-04 22:10

Yup, I’m glad it helped!

djmick | 2021-02-05 00:06