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