Hey there,
I'm working on a 2D Tower Defense with a top down view.
I have 4 different sprite for 4 different movement N.S.W.E.
I know how to set the animation and change them for the played, depending on what input is pressed.

I want to apply 4 direction to the enemies who's path is defined by getsimplepath.
Is there a function that return me a vector 2 that i can identify as "going left" "going right" ?

Without the "input" from a key i have no clue how to do it.
Thx !

in Engine
edited

For a node that moves by repeatedly setting their position (such that velocity isn't actually known, like it would for `KinematicBody2D` or `RigidBody2D`), you can determine the direction an enemy is going by comparing its current position and its position from the last frame.

``````var _position_last_frame := Vector2()
var _cardinal_direction = 0

func _physics_process(delta):
# Get motion vector between previous and current position
var motion = position - _position_last_frame

# If the node actually moved, we'll recompute its direction.
# If it didn't, we'll just the last known one.
if motion.length() > 0.0001:
# Now if you want a value between N.S.W.E,
# you can use the angle of the motion.
# I came up with this formula last time I needed it:
_cardinal_direction = int(4.0 * (motion.rotated(PI / 4.0).angle() + PI) / TAU)

# And now you have it!
# You can even use it with an array since it's like an index
match _cardinal_direction:
0:
print("West")
1:
print("North")
2:
print("East")
3:
print("South")

# Remember our current position for next frame
_position_last_frame = position
``````

I used a fancy formula here but if you just need the `motion` vector, you can also work out something that suits you, by checking `motion.x` and `motion.y`.

by (29,088 points)
selected

darn ! I'm in 2d.
This is for a kinematic2d node.

I'm looking at stepify() but that method isn't part of the ************** class sadly.

`stepify` is a global function, it can be used anywhere.

Answer updated for 2D. I guess `stepify` can also work the same way with angles, though you need to make sure a small offset is added to even out the "range" of each direction, see visualisation I made here (for 8 directions but the concept is the same with 4): https://github.com/godotengine/godot-proposals/issues/566#issuecomment-596266660

thx ! I will give it a shot now !
I mentioned MOTION + previous/new frame position on godot discord and it looks like everyone agreed to be the best solution.

Tho, i will have 100-500 monsters at once on the map.
Which one of the methods between stopify and motion is lighter regarding CPU consumption in your opinion ?

are you confident truncating the direction is the right thing, as opposed to rounding it?

Can you post your `stepify`? Chances are it might be slightly faster because it moves a few of the operations from my formula to engine code.

I honestly didnt get a chance to make it work as kinematicbody doesn't work with stopify...

This solved my problem to the letter. Thank you very much for posting!