Hello, so currently I’m having an issue with getting animation to work smoothly. So far most of what I wanted is working as intended except that when going from an idle animation into an attack animation, it sometimes stutters a bit at the start, and secondly if I spam enough I can get the attack animation to endlessly loop as seen in the video I provided down below. Normally if I don’t spam it works the way I want to where the attack animation must complete before the character can even move.
But yes, I need help solving this weird endless animation glitch. Any and all help would be appreciative.
Here is the current code with a video of the issue. If you need any more information let me know and I’ll gladly provide more.
extends CharacterBody2D
var speed := 20000.0
var direction : Vector2 = Vector2.ZERO
var is_attacking : bool = false
func _ready() -> void:
%AnimationTree.active = true
%AnimationTree.animation_finished.connect(self._on_animation_finished)
func _process(delta: float) -> void:
if Input.is_action_just_pressed("attack") and not is_attacking:
start_attack()
if not is_attacking:
direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
move_character(direction,delta)
update_animation_parameters()
func move_character(direction: Vector2, delta: float) -> void:
velocity = direction * speed * delta
position += velocity * delta
func update_animation_parameters():
if velocity == Vector2.ZERO and not is_attacking:
%AnimationTree["parameters/conditions/idle"] = true
%AnimationTree["parameters/conditions/is_moving"] = false
elif velocity != Vector2.ZERO and not is_attacking:
%AnimationTree["parameters/conditions/idle"] = false
%AnimationTree["parameters/conditions/is_moving"] = true
if Input.is_action_just_pressed("attack") and not is_attacking:
is_attacking = true
%AnimationTree["parameters/conditions/attack"] = true
if direction != Vector2.ZERO:
$AnimationTree["parameters/attack/blend_position"] = direction
$AnimationTree["parameters/idle/blend_position"] = direction
$AnimationTree["parameters/move/blend_position"] = direction
func start_attack():
%AnimationTree["parameters/conditions/idle"] = false
is_attacking = true
%AnimationTree["parameters/conditions/attack"] = true
func _on_animation_finished(anim_name: String) -> void:
if anim_name.begins_with("attack_"):
is_attacking = false
%AnimationTree["parameters/conditions/attack"] = false
Stuttering: The stuttering at the start of the attack animation is likely due to a mismatch between the timing of the input action and the animation’s start. Godot may try to blend animations, causing a brief hiccup.
Endless Loop: The endless loop occurs because the attack condition is never explicitly set back to false within the _process function. This allows the attack animation to trigger repeatedly if the input is spammed.
Here are some Solutions that might help:
Input Buffering and Cooldown: Instead of immediately starting the attack on the first input press, use a short input buffer (e.g., 0.1 seconds). This allows for smoother transitions from idle to attack. Also introduce a cooldown period after each attack to prevent spamming and ensure animations complete.
Explicit State Management:
Use a state machine or boolean flags to explicitly track whether the character is idle, moving, or attacking. This helps ensure proper animation transitions and prevents unexpected behavior. For example you can use this Asset for that.