• Godot HelpProgramming
  • How i can find out what collided with an area 2d and access a variable from its owner node?

OK so i am working on a combat mechanism in my game but i need to check what enemy collided with my player's attack detector(an area 2d with a collision shape 2d node as a child). The area 2d is set to only detect enemy nodes but i don't know how i can access a variable(the knock-back variable, i need it to check how hard the enemy should hit. I am going to put this variable in every new enemy's script) from the collider's owner node's script.

Are you familiar with the Area2D signals? The signal area_entered is exactly what you want. But in this case I would suggest having the enemy dealing with the collision detection.

You can connect the signals in the following way: 1. Go to your enemy scene and click in the Collision Shape node 2. In the right side of your editor (assuming you are in the default template for Godot 3.4) right from the inspector tab there is the "node" tab. 3. Since I assume your enemy is also a Collision Shape with an Area2D it must have the area_entered signal there. 4. Right click it and connect it to itself (with the Collision Shape that has the enemy script). 5. It will create a function along the lines with _on_Enemy_area_entered(area)

You can read more about using signals in this documentation article.

Inside this created function you can check if the area entered in the Enemy's Area2D is the player. I usually do this adding the player scene or player hitbox to a "player" group (you can do this going to your player scene -> Node tab in the right side of the editor -> group -> write "player" and add it), then your function would look something like:

func _on_Enemy_area_entered(area):
	if area.is_in_group("player"):
		area.take_damage(knock_back_value)

Where knock_back_value would be a variable inside the enemy script and take_damage a method inside the player script that would apply the knock back how you want.

@bored_paramecium said: Are you familiar with the Area2D signals? The signal area_entered is exactly what you want.

You can connect the signals in the following way: 1. Go to your enemy scene and click in the Collision Shape node 2. In the right side of your editor (assuming you are in the default template for Godot 3.4) right from the inspector tab there is the "node" tab. 3. Since I assume your enemy is also a Collision Shape with an Area2D it must have the area_entered signal there. 4. Right click it and connect it to itself (with the Collision Shape that has the enemy script). 5. It will create a function along the lines with _on_Enemy_area_entered(area)

You can read more about using signals in this documentation article.

Inside this created function you can check if the area entered in the Enemy's Area2D is the player. I usually do this adding the player scene to a "player" group (you can do this going to your player scene -> Node tab in the right side of the editor -> group -> write "player" and add it), then your function would look something like:

func _on_Enemy_area_entered(area):
	if area.is_in_group("player"):
		area.take_knock_back(knock_back_value)

Where knock_back_value would be a variable inside the enemy script and take_damage a method inside the player script that would apply the knock back how you want.

Of course i know how to use the area 2d signals. But that's not the main concern. I have the enemy as a kinematic body 2d with a collision shape 2d as a child. I don't get how the "area.take_knock_back(knock_back_value)" line works. Can you tell me what this line does and how it works? I am still learning Godot and Gd-script. Also you left me on a cliff hanger on one of my previous questions. I still haven't figured out how i am gonna go about on implementing wall-jump. But that's not the main topic right now.

The line works because the area parameter passes the Area2D object that entered in the area of the signal emitter, in my example it would be the player. I assume you have a function in the player script that deals when they receive damage, that function would be take_damage(value). Since you passed the player object as a parameter to the _on_Enemy_area_entered(area) you can access its "inner function" (a method) with the dot . passing the enemy's knock_back as a parameter. Basically what you are doing is calling the take_damage() function in the player script from the enemy script.

Are you familiar with OOP (Object Oriented Programing)? If not, it would be good to have an overview about it, since it's wildly used in Godot, game and software development in general.

You didn't mention your enemy was a Kinematic Body, so I assumed it was an Area2D. But this is minimal, the only change you need to make in the instructions I passed you is that now the Player's Area2D should be the one detecting the overlap. You can use the body_entered signal from the Area2D to detect when the enemy's body enters in the Player's Area2D, then in the _on_Player_body_entered(body) something like:

func _on_Player_body_entered(body):
	if body.is_in_group("enemies"):
		 # knock_back_damage  is a variable in your enemy script 
		var damage = body.knock_back_damage
		 # take_damage is a function in your player that deals with the damage taken
		take_damage(damage)

In other words, you can access a variable of other object using the ..

I didn't continue with your answer in the other topic because you accepted an answer and because I don't know what more I could do. I would probably need to re implement all your code locally and run tests by myself, something I do not have time to perform.

10 months later