#Attack animations not working.

1 messages · Page 1 of 1 (latest)

glacial surge
#

For some reason the animation of the sword is not working. I dont know why, i tought that maybe was because of conflict between animations, but now i really dont know the cause.

Im using animation libraries to organize different animations in a single animationPlayer. And Im using a state machine too, but i think its a problem on my attack state. So here it is

class_name Attack

@onready var animations = $"../../AnimationPlayer"
@export var player : CharacterBody2D
@onready var weapon = $"../../Weapons"


func _on_enter() -> void:
    var attack_direction = player.player_direction
    
    if attack_direction == Vector2.ZERO:
        attack_direction = player.last_direction
        
    # Normaliza direções diagonais para os eixos principais
    if abs(attack_direction.x) > abs(attack_direction.y):
        attack_direction.y = 0  # Mantém apenas o eixo horizontal
        attack_direction.x = sign(attack_direction.x)  # Converte para -1 ou 1
    else:
        attack_direction.x = 0  # Mantém apenas o eixo vertical
        attack_direction.y = sign(attack_direction.y)  # Converte para -1 ou 1
        
    print("Direção normalizada:", attack_direction)
    
    if attack_direction == Vector2.UP:
        animations.play("Sword/attackUp")
    elif attack_direction == Vector2.DOWN:
        animations.play("Sword/attackDown")
    elif attack_direction == Vector2.LEFT:
        animations.play("Sword/attackLeft")
    elif attack_direction == Vector2.RIGHT:
        animations.play("Sword/attackRight")
    print("Animação iniciada:", animations.current_animation)


func _on_animation_finished(anim_name):
    print("Animação terminada:", anim_name)
    Transitioned.emit("idle")  

func _on_exit() -> void:
    animations.stop() ```

On the print is how i organized the nodes on the player node
glacial surge
#

i was making based on this tutorial: https://www.youtube.com/watch?v=kPSyUEQds6M&t=3s

Hi and welcome to this tutorial series, where I will show you how to make a 2D ARPG in Godot 4.1.

Support the channel on Patreon: https://patreon.com/MakerTech
Support the channel with a Youtube membership: https://www.youtube.com/channel/UCZfXxUfpS7q-v1gsMY-hQtA/join
Join the Discord server: https://discord.gg/7zKMaZDycE
https://youtube.com/pl...

▶ Play video
stray geyser
#

when you print out the attack direction, what is it?

glacial surge
#

Oh sorry, its in portuguese, my mother language. let me explain the prints

stray geyser
#

Sorry, I meant, can you print out the variable attack_direction?

glacial surge
#

they are all for debug, for me to follow what animation is entering and wich is exiting

"print("Direção normalizada:", attack_direction)"

tranlates to "normalized direction", this im geting the normalized direction of the attack animation, cause i was having trouble when attacking using diagonals

"print("Animação iniciada:", animations.current_animation)"

translates to "animation iniciated", this is to know wich animation started

"print("Animação terminada:", anim_name)"

translates to "animation terminated", to show what animation has ended

stray geyser
#

it might not match any of the vectors

#

I think that maybe none of the if statement conditions are true

#

and no animation will play, but i'm not sure

glacial surge
#

the print was:

Direção normalizada:(-1.0, 0.0)
Animação iniciada:Sword/attackLeft

Direção normalizada:(1.0, 0.0)
Animação iniciada:Sword/attackRight

Direção normalizada:(0.0, -1.0)
Animação iniciada:Sword/attackUp

Direção normalizada:(0.0, 1.0)
Animação iniciada:Sword/attackDown

#

direção normalizada -> normalized direction
animação iniciada -> animation inicialized

stray geyser
#

Okay, so the animation does change correctly

glacial surge
#

i will put the prints in english

stray geyser
#

There are no errors when you run the code?

glacial surge
#

yeah, but with this test i found other problem, the animation are "restarting" when the character is walking, i think i can resolve this

glacial surge
stray geyser
#

what does the animation look like when you run it in the editor?

glacial surge
#

on the animationplayer? completely normal

stray geyser
#

the animationplayer is set to normal speed?

glacial surge
#

yes

#

i created on a library

stray geyser
#

okay, so the animationplayer's speed is never changed in code?

glacial surge
#

heres my animation library

stray geyser
#

it looks like it's going directly to the end frame

glacial surge
#

yeah, the character is normal, but the animation of the sword is just the first frame

stray geyser
#

It should print out when it terminates the animation? Does it do that?

glacial surge
#

its beeing a pain in the ass this issue, and i feel that is something simple yk?

glacial surge
stray geyser
#

when stop is called on the animationplayer, it will reset the animation. is it possible it's calling that right away?

glacial surge
#

just that the animation started

#

so its not ending

stray geyser
#

i guess it exits the state before the animation ends

glacial surge
#

yeah... lemme see my other states

#
class_name PlayerIdle

@export var player: CharacterBody2D
@onready var animations = $"../../AnimationPlayer"

var last_direction: Vector2 = Vector2.DOWN  # Define uma direção padrão inicial

func _physics_process(delta: float) -> void:
    
    var direction = gameInputEvents.movement_input()

    # Se houver movimento, muda para Walk
    if direction != Vector2.ZERO:
        last_direction = direction  # Armazena a última direção
        Transitioned.emit("Walk")
        return

    # Mantém a animação Idle na última direção usada
    if last_direction.y < 0:
        animations.play("Normal/idleUp")
    elif last_direction.y > 0:
        animations.play("Normal/idleDown")
    elif last_direction.x < 0:
        animations.play("Normal/idleLeft")
    elif last_direction.x > 0:
        animations.play("Normal/idleRight")

    if Input.is_action_just_pressed("attack"):
        Transitioned.emit("Attack")

this is my idle state

#

its called on the animation finished functions

stray geyser
#

is there anywhere else in the code that will cause a state change?

glacial surge
#

currently i have 4 states. "idle", "walk" , "attack" and "dodge"

on the idle state, "walk" and "attack" can be called

on the walk state, "attack" and "dodge" can be called

on the attack and dodge states both just call "idle" when finished

stray geyser
#

You disable the other states that are not active, right?

glacial surge
#

oh yeah, the state machine does that automaticaly

stray geyser
#

okay, then i guess you need to find the code that exits the state early

glacial surge
#
class_name NodeStateMachine
extends Node

@export var initial_node_state : State

var node_states : Dictionary = {}
var current_node_state : State
var current_node_state_name : String

func _ready() -> void:
    for child in get_children():
        if child is State:
            node_states[child.name.to_lower()] = child
            child.Transitioned.connect(transition_to)
    
    if initial_node_state:
        initial_node_state._on_enter()
        current_node_state = initial_node_state
        current_node_state_name = current_node_state.name.to_lower()
    else:
        push_error("Initial node state is not set in the state machine.")

func _process(delta : float) -> void:
    if current_node_state:
        current_node_state._on_process(delta)

func _physics_process(delta: float) -> void:
    if current_node_state:
        current_node_state._on_physics_process(delta)
        current_node_state._on_next_transitions()

func transition_to(node_state_name : String) -> void:
    if node_state_name.to_lower() == current_node_state_name:
        #print("Already in state: ", node_state_name)
        return
    
    var new_node_state = node_states.get(node_state_name.to_lower())
    
    if !new_node_state:
        push_error("State not found: ", node_state_name)
        return
    
    if current_node_state:
        current_node_state._on_exit()
    
    new_node_state._on_enter()
    
    current_node_state = new_node_state
    current_node_state_name = current_node_state.name.to_lower()
    #print("Transitioned to state: ", current_node_state_name)

here she is

stray geyser
#

where is the code that disables the state

#

the player idle state has the physics_process function, which is called every frame unless the node itself is disabled

#

but there is no code for disabling it

glacial surge
#

oh you think the idle is called all the time?

stray geyser
#

you have the statemachine call the _on_physics_process function which is a different function

#

yes

glacial surge
#

oh that makes sense actually

#

oh my god i love you, the animation played but dindt stoped

#

BUT IT PLAYED

stray geyser
#

np 👍