How to create enemy that follows player when in Area2D (2D Platformer)

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

I was following this tutorial when I realized it wasn’t what I really needed. I need the enemy to just stay still and if the player enters its Area2D then it will follow the player.

I got as far as connecting body_entered signal of the Area2D to the kinematicbody, but I have no idea what to do after that, how do I make it follow the player?

Do you mean so it moves in the player’s direction? If so, you can check if the player’s position.x value is higher or lower than the enemy and move it in the correct direction.

Magso | 2020-08-03 21:46

:bust_in_silhouette: Reply From: chugwig

Be careful with this line of thinking, following a tutorial until step 5 and then realizing it’s not exactly what you need and so you ask a question on a forum expecting someone to give you exactly what you need is a dangerous practice seen in many professions, but especially those related to programming.

Let’s think about what you want to do:

  • The enemy is watching an area for the player.
  • If the player is in this area, you want the enemy to approach the player.
  • If the player leaves this area, you want the enemy to stop immediately.

So you’ve already got step 1 done and half of step 2. The question is what to connect the body_entered signal to, and the answer is pretty much anything that eventually accomplishes the goal of “approach the player”. The big issue is that a lot of it depends on how the rest of your game is set up, so here I’ll list a few suggestions:

  • Maybe your enemy is more about charging immediately in a straight line, and so once the player enters the area the enemy will head in that direction until the player leaves the area and the enemy stops.
    • You could do this by setting a velocity for the enemy in the function called by the body_entered signal (for typing sake, I’ll be calling this “the callback” for the rest of the post).
    • Then you’d move with that velocity in your _physics_process function.
    • How you’d set the velocity to be in the direction of the player is something I’ll touch on at the end.
  • More likely you want an enemy that is heading towards the player wherever they are in the area.
    • The idea is similar to the above, but instead of storing a velocity in the callback you’ll instead store the object you collided with itself (which is a parameter to the callback).
    • Then you’d move towards that player in your _physics_process function, whether directly moving in that direction, using a velocity, acceleration, whatever you choose (this is part of what I was saying about it really depending on your specific game’s setup).
  • Or maybe your enemy is a mix of the above, and it’ll move itself to the point where the player entered but it won’t be actively hunting the player while they’re in the area. I’ll leave how you’d accomplish this and the many other possible variations to you.

Now what about heading in the direction of the player? Well you’re going to need to mess with vectors, specifically subtracting and then normalizing them. The vectors you’ll be looking at are the position of your enemy and the position of your player, making sure they’re both relative to the same point (local transform for example only works if they’re both sharing the same parent, global_position is the safest bet afaik).

Once you have the two vectors, subtract them normally (with a - ) and then call .normalized() on the result. For example “(B-A).normalized()”, and then you can multiply the normalized vector by whatever speed you want the enemy to move at (or acceleration, or etc…).

As a final note, you’ll also need to set up the body_exited signal to clear out whatever you set when the body entered. Using the examples I gave before, if you didn’t set up body_exited to another callback that clears the variables you’d get:

  • Your enemy charging endlessly in the direction you set.
  • Your enemy is charging at the player even after they leave the area.
  • Depends on what kind of mechanic you create, for the example I gave there’d be no issue since the enemy was moving to a point in space and will eventually reach it. Maybe you’d want code to have it stop chasing that point once it reaches it otherwise it might bob around it (unless it landed exactly on the point it wanted and then it’d just be trying to move 0,0 each time which still isn’t great).

Yeah, I understand what you mean. But I did search past forums, and other videos - I even tried messing with it myself but I couldn’t get it to work.

Thanks for the help, I really appreciate it! :slight_smile:

Pneuma | 2020-08-04 05:10