My idle animation is not playing

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

So I have this code:

extends KinematicBody2D

onready var front: = $UI/Joystick/front_sprite
onready var back: = $UI/Joystick/back_sprite
onready var player:= $"."
var distancebetween_front_and_backx:float = 0.0
var distancebetween_front_and_backy:float = 0.0
var anglebetween: = 0
var velocity = Vector2.ZERO
export(int) var speed = 1
onready var animations = $AnimationPlayer
onready var weapon = $Weapon


func _ready():
	animations.play("bob")

func _physics_process(delta):
	velocity = values_between_frontandback() * speed
	if velocity == Vector2.ZERO:
		$AnimationTree.get("parameters/playback").travel("Idle")
	else:
		$AnimationTree.get("parameters/playback").travel("Walk")
		$AnimationTree.set("parameters/Idle/blend_position", velocity)
		$AnimationTree.set("parameters/Walk/blend_position", velocity)
	move_and_slide(velocity * speed)


func _unhandled_input(event):
	if event.is_action_pressed("attack"):
		weapon.attack()


func values_between_frontandback() -> Vector2:
	var vec : Vector2 = front.global_position - back.global_position
	return vec
	
func _process(delta: float) -> void:
	pass

Which should play an idle animation from the animation tree when the player is standing still(Vector2.ZERO).This works when the game first starts,but as soon as I move the joystick and let go of it again it just plays the walk animation.

:bust_in_silhouette: Reply From: jgodfrey

I assume the issue is caused by minor floating point errors. Try changing this:

 if velocity == Vector2.ZERO:

to this…

if velocity.is_equal_approx(Vector2.ZERO):

If it still doesn’t work after the above change, I’d suggest that you print out the value of velocity just above the line in question and then figure out why you’re not getting a result that’s nearly equal to Vector2.ZERO.

jgodfrey | 2023-03-18 19:00

I think I found why it isn’t working .I used print to show the velocity and it starts out at 0 but after I move the joystick and let go of it it goes to 0.000061,0.000122 not 0,0.Anyway I can fix that? Also I tried using your code it didn’t work

This is the joystick code ,I took it from some youtube video ,don’t remember which one:

    extends Node2D


signal joystick_released()


onready var back: Sprite = $back_sprite
onready var front: Sprite = $front_sprite
export var min_height_of_joystick : int = 1300
export var ease_value: float = 0.25
export var range_of_joystick: int = 100 
var screensize: Vector2 = Vector2.ZERO

func _ready() -> void:
	screensize = get_viewport_rect().size
	front_extents_maker()


func _process(delta: float) -> void:
	front_related() 
	if front.global_position.distance_to(back.global_position) <= 1.0:
		emit_signal("joystick_released")


func front_related() -> void:
	var mouse_pos: = get_global_mouse_position()
	if Input.is_mouse_button_pressed(1):
		front.global_position = lerp(front.global_position, mouse_pos, ease_value)
		front.global_position.x = clamp (front.global_position.x, front_extents_maker()[0], front_extents_maker()[1])
		front.global_position.y = clamp (front.global_position.y, front_extents_maker()[2], front_extents_maker()[3])
	else:
		front.global_position = lerp(front.global_position, back.global_position, ease_value)


func _input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		var Y_max_height_for_back: = screensize.y - range_of_joystick
		if event.position.y < Y_max_height_for_back and event.position.y > min_height_of_joystick:
			back.global_position = event.position
			front_extents_maker()
		else:
			pass


func front_extents_maker() -> Array:
	var left_max_size_x: float = back.global_position.x - range_of_joystick
	var right_max_size_x: float = back.global_position.x + range_of_joystick
	var top_max_size_y: float = back.global_position.y - range_of_joystick
	var bottom_max_size_y: float = back.global_position.y + range_of_joystick
	var arr: Array = [left_max_size_x, right_max_size_x, top_max_size_y, bottom_max_size_y]
	return arr

Skizi | 2023-03-19 18:51

Right - the problem is definitely that your joystick isn’t returning to exactly Vector2.ZERO, so your if check fails. That’s exactly what my proposed change was attempting to fix. With the proposed change, the check should return true when the specified vector is very near zero, but it doesn’t have to be exactly zero.

However, based on the vector value you posted (0.000061,0.000122), that’s NOT close enough to zero for is_equal_approx() to return true.

Ideally, the returned vector would be fixed in the virtual joystick code. However, short of that, a quick fix might be to just base your idle check on the length of the your velocity vector.

For example, the vector you posted has a length of approx 0.000136. So, knowing that, you could change your original code to something like:

velocity = values_between_frontandback() * speed
if velocity.length() < 0.0002:
    # idle...

You might have to tweak that value to taste, but it would work for the vector you posted…

jgodfrey | 2023-03-19 19:21

Yep that fixed it thank you very much!

Skizi | 2023-03-20 14:06