Setting animation direction in a tile map with astargrid movement

Godot Version

4.4.1

Question

`I don’t know how to implement character animations based on in which direction the character is moving. I’m new to coding and this is my first game. This is the code I basically copied based on a tutorial but I really like the movement so I’d like to keep it. The animations are 4 idle in 4 directions and 4 move animations in 4 directions.

`

For future reference, just copy/paste your code. Images are strictly worse because we can’t copy/paste, highlight, etc.

Surround your code with triple tick marks (the key to the left of the “1” key on most keyboards) to format it:
```
func _ready():
pass
```
becomes

func _ready():
    pass

On to your question:
You can set up some enum that will match up with the various facing directions, and handle those however you want later (i.e. apply simple rotation to the sprite, use a different sprite for each direction, whatever).

enum FacingDirection {
    LEFT, RIGHT, UP, DOWN
}

In _physics_process, you can do something like

var walking_direction = target_position - global_position
var facing_direction
if (abs(walking_direction.x) > abs(walking_direction.y)):  # Walking left or right, mostly
    if walking_direction.x > 0:
        facing_direction = FacingDirection.RIGHT
    else:
        facing_direction = FacingDirection.LEFT
else:  # Walking up/down, mostly
    if walking_direction.y > 0:
        facing_direction = FacingDirection.DOWN
    else:
        facing_direction = FacingDirection.UP

Then you can do whatever you want with the facing_direction.

For example:

if facing_direction == FacingDirection.UP:
    some_code_to_play_the_up_animation
elif facing_direction == FacingDirection.DOWN:
    some_code_to_play_the_down_animation
etc

Noted. Will try this tomorow, I’m heading to sleep. Will reply again when I try this. Thanks

func _physics_process(_delta):
		if current_id_path.is_empty():
			return
		if is_moving == false:
			target_position = tile_map.map_to_local(current_id_path.front())
			is_moving = true
		
		global_position = global_position.move_toward(target_position, 1)
		
		if global_position == target_position:
				current_id_path.pop_front() 
				
				if current_id_path.is_empty() == false:
					target_position = tile_map.map_to_local(current_id_path.front())
				else:
					is_moving = false
					
		var walking_direction = target_position - global_position
		var facing_direction
		if (abs(walking_direction.x) > abs(walking_direction.y)):
			if walking_direction.x > 0:						#walking x axis
				facing_direction = FacingDirection.RIGHT
				animation_player.play("walking_right")
			else:
				facing_direction = FacingDirection.LEFT
				animation_player.play("walking_left")
		else: 												#walking y axis
			if walking_direction.y > 0:
				facing_direction = FacingDirection.DOWN
				animation_player.play("walking_down")
			else:
				facing_direction = FacingDirection.UP
				animation_player.play("walking_up")

Hello again. Tried to implement the code and it helped a lot but there are a few flaws. When launching debug screen the character by default spawns facing up and when the character stops moving it goes back to looking up. How can I make it so that when the character stops moving it keeps the animation direction and switch from “waking_x.direction” to “idle_x.direction”. And also I want it to spawn looking down. Thanksss

Sure. For things that you want to happen when the character spawns in, you can set this up in _ready().

func _ready():
    animation_player.play("walking_down")

The reason the character faces up when it stops moving is a subtle bug in the various if statements we added: If the character has reached the target, then walking_direction = target_position - global_position will be (0, 0). This means we end up in both else clauses, because it is not the case that abs(walking_position.x) > abs(walking_position.y), and it is also not the case that walking_direction.y > 0.

You could just do something like

		if (abs(walking_direction.x) > abs(walking_direction.y)):
			if walking_direction.x > 0:						#walking x axis
				facing_direction = FacingDirection.RIGHT
				animation_player.play("walking_right")
			else:
				facing_direction = FacingDirection.LEFT
				animation_player.play("walking_left")
		elif abs(walking_direction.y) > abs(walking_direction.x): 												#walking y axis
			if walking_direction.y > 0:
				facing_direction = FacingDirection.DOWN
				animation_player.play("walking_down")
			else:
				facing_direction = FacingDirection.UP
				animation_player.play("walking_up")

(I changed the main else clause to explicitly exclude the case where walking_direction.y and walking_direction.x are both 0).

Also, I’m noticing that you’re directly playing the animations in these clauses, which is fine, but it means that you’re not using the FacingDirection enum, so you can just delete those lines (unless you’re using facing_direction elsewhere)

This code worked as well i just added a return after every if and else statement. Thanks though it’s a lot shorter now :DD