animationplayer won't transition between animations

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

hey im trying to make simple character controller but i’m having problems with the transitions between animations here’s my code:

var previous_dir
if _direction == Vector2(1,0):
	$Animation.play("walk_right")
	previous_dir = Vector2(1,0)
	if Input.is_action_pressed("interract"):
		$Animation.play("interract_right")
elif _direction == Vector2(-1,0):
	$Animation.play("walk_left")
	previous_dir = Vector2(-1,0)
	if Input.is_action_pressed("interract"):
		$Animation.play("interract_left")
elif _direction.y == 1:
	$Animation.play("walk_down")
	previous_dir = Vector2(0,1)
	if Input.is_action_pressed("interract"):
		$Animation.play("interract_down")
elif _direction.y == -1:
	$Animation.play("walk_up")
	previous_dir = Vector2(0,-1)
	if Input.is_action_pressed("interract"):
		$Animation.play("interract_up")
elif _direction == Vector2(0,0):
	$Animation.stop()
	if previous_dir == Vector2(1,0):
		$Animation.play("Idle_right")
	elif previous_dir == Vector2(-1,0):
		$Animation.play("Idle_left")
	elif previous_dir == Vector2(0,1):
		$Animation.play("Idle")
	elif previous_dir == Vector2(0,-1):
		$Animation.play("Idle_up")

it plays the walking and interacting animations fine but for some reason it doesn’t play the idle

also isn’t there an easier way to write all of this
thanks for taking a look at my post :slight_smile:

:bust_in_silhouette: Reply From: whiteshampoo

Very untested Code:

extends Node2D # Change this!

# Never write 2 times the same node with $
# If you rename a Node, you need to search every line with the name
# So it is only one line
onready var anim : AnimationPlayer = $Animation

# Looking right into your face by default
var previous_dir : Vector2 = Vector2.DOWN

# Set some strings to put them together
const STR_DIR : Dictionary = {	Vector2.UP: "up",
								Vector2.DOWN: "down",
								Vector2.LEFT: "left",
								Vector2.RIGHT: "right"}
const STR_IDLE : String = "Idle_" # should be lowercase
const STR_WALK : String = "walk_"
const STR_ACT : String = "interract_" # typo!

# BTW: Static Typing FTW!

func _ready() -> void:
	# Examples: (check the debug output!)
	animate(Vector2.UP, false)
	animate(Vector2.UP, false)
	animate(Vector2.UP, true)
	animate(Vector2.RIGHT, true)
	animate(Vector2.RIGHT, false)
	animate(Vector2.ZERO, false)
	animate(Vector2.ZERO, true)
	
	# You might want to use it like this:
	# animate(dir, Input.is_action_pressed("interract"))

# Lets make a funny method!
func animate(_direction : Vector2, _interact : bool = false) -> void:
	match _direction:
		Vector2.UP, Vector2.DOWN, Vector2.LEFT, Vector2.RIGHT:
			previous_dir = _direction # Set this if movment
			
		Vector2.ZERO:
			pass # keep if no movement
			
		_: # cry if something is fishy
			assert(false, "Not a straight direction: " + str(_direction))
			
	var animation : String = STR_DIR[previous_dir]
		
	# --- The next part might need to be modified. Depends on your needs! ---
	if _interact: # I think you want interaction as priority. I might be wrong!
		animation = STR_ACT + animation
	else:
		if _direction != Vector2.ZERO: 
			animation = STR_WALK + animation # Walk, if movement ...
		else: 
			animation = STR_IDLE + animation # ... and idle if not
	# -----------------------------------------------------------------------
	
	# Sweet debug output
	print_debug("Animation: ", animation)
	anim.play(animation)

It should be pretty self-explanatory with the comments.
You might need to change “Idle” to “Idle_down”

Thats how i would do it.
Feel free to ask, if something is unclear. And please tell me, if it works!

EDIT:
oh, the problem with your code was probably, that previous_dir was not ‘global’. If this is in your function/method, it will be reseted everytime it is declared.

Wow! thanks for this answer and for taking the time to make this function! i could’ve asked for a better response
THANKS !!!
:slight_smile:

ROBOTOO007 | 2020-06-10 19:23