#Animation doesnt loop

79 messages · Page 1 of 1 (latest)

sterile skiff
#

hello, i have a problem where the animation doesnt loop because the process tries to update it every frame even though it should be updates everytime the angle changes. Im new so idk how to write a function that would do that so please help 😦

#

the sprite needs to blink

#

heres the code:

#


var cardinal_direction = Vector2.DOWN
var direction = Vector2.ZERO
var angle = 0

const DIR_4 = [ Vector2.RIGHT, Vector2.DOWN, Vector2.LEFT, Vector2.UP ]


@onready var anim = $AnimationPlayer
@onready var state_machine : PlayerStateMachine = $StateMachine
@onready var attack = $StateMachine/Attack


func _ready():
    state_machine.Initialize(self)


func _physics_process(_delta):
    direction = Input.get_vector("left", "right", "up", "down")
    move_and_slide()

func _process(_delta):
    var mouse = get_local_mouse_position()
    angle = snappedf(mouse.angle(), PI / 4) / (PI / 4)
    angle = wrapi(int(angle), 0, 8)
    
    print (state_machine.current_state)

func set_direction():
    if direction == Vector2.ZERO:
        return false

    var direction_id : int = int( round( ( direction + cardinal_direction * 0.1 ).angle() / TAU * DIR_4.size() ) )
    var new_dir = DIR_4[ direction_id ]
    
    if new_dir == cardinal_direction:
        return false

    cardinal_direction = new_dir
    return true
    

func update_walk_animation():
    anim.play( "walk" + anim_walk_direction() )
    
func update_animation( state : String ):
    anim.play( state + anim_direction() )
    pass

func update_attack_animation():
    anim.play("flash" + str(angle))


func update_idle_animation():
    anim.play ("idle" + str(angle))

func anim_direction():
    if cardinal_direction == Vector2.RIGHT:
        return "0"
    elif cardinal_direction == Vector2.DOWN:
        return "2"
    elif cardinal_direction == Vector2.LEFT:
        return "4"
    else:
        return "6"

func anim_walk_direction():
    if direction == Vector2.RIGHT:
        return "0"
    elif direction == Vector2.DOWN:
        return "2"
    elif direction == Vector2.LEFT:
        return "4"
    else:
        return "6"
#

var attacking = false

@onready var walk : State = $"../Walk"
@onready var idle : State = $"../Idle"


@export var move_speed : float = 100.0


## What happens when the player enters this State?
func enter() -> void:
    attacking = true
    pass


## What happens when the player exits this State?
func exit() -> void:
    pass


## What happens during the _process update in this State?
func process( _delta : float ) -> State:
    player.update_attack_animation()
    player.velocity = player.direction * move_speed
    
    if attacking == false:
        if player.direction == Vector2.ZERO:
            return idle
        else:
            return walk
    return null

## What happens during the _physics_process update in this State?
func physics( _delta : float ) -> State:
    return null


## What happens with input events in this State?
func handle_input( _event: InputEvent ) -> State:
    if _event.is_action_pressed("attack"):
        end_attack()
    return null


func end_attack() -> void:
    attacking = false
#

and for the state

dry dune
#

anim.loop = linear

sterile skiff
#

where

dry dune
#

try this one

#

in code

sterile skiff
#

bro but where

#

do i have to write it under the animation or as a seperate variable in the playerscript

dry dune
#

in your code when you supposed to use animation xd

#

or u can set loop in inspector

#

when you clicking on animation player node

sterile skiff
#

its already set to ping pong

dry dune
#

ok

#

and still doesn't work

sterile skiff
#

yes

dry dune
#

k well let's find out

sterile skiff
#

i tried with some bad code and it is because it tries to update every frame

#

the solution is that it should play the animation on enter or when the angle changes

dry dune
#

the blink animation?

#

or when idle

sterile skiff
#

the blink

#

the idle works

dry dune
sterile skiff
#

yes

dry dune
#

and on video it plays multiple times

#

cuz i don't understand yet 😞

sterile skiff
#

it plays the blink animation once on video

#

look man

dry dune
#

5 times

sterile skiff
#

the blink animation has to play like the idle animation, it has to loop. and it doesnt, it only plays it one time

dry dune
#

when you rotate

sterile skiff
#

yes when i rotate

#

but when i stay still it only plays one time

#

wait lemme show you how its supposed to look

dry dune
#

Yes, it would be understandable

sterile skiff
#

sorry wrong one

#

this one

#

you see when i put the animation on enter it doesnt rotate but it loops the animation

#

thats how its supposed to look like in every direction

#

but it doesnt because the animation is in the process function and the process function tries to update the animation constantly, thats why it doesnt loop

#

and it can be fixxed if the animation only plays once the angle of rotation changes, but i dont know how to write that function

dry dune
#

i will text later

sterile skiff
#

alright man thanks for trying to help me

dry dune
#

but leave this open

sterile skiff
#

have a good night

dry dune
#

same for you

brisk jewel
#

You should be able to check if the current direction is the same as the previous direction by storing the previous direction as another variable

#

There's also the .is_playing() method from AnimationPlayer that may be helpful, depending

sterile skiff
brisk jewel
#

?

brisk jewel
#

I'm not sure I understand what you're saying, could you elaborate?

sterile skiff
#

so, you could solve this problem by playing the animation only when the direction changes, right?

sterile skiff
#

to keep it simple

brisk jewel
#

You mentioned that using prev_angle to compare against didn't work

#

I didn't quite understand what you were saying to explain why it didn't work

sterile skiff
#

it didnt because you enter the state with angle 0, and when you dont move your mouse you stay in angle 0, so the previous angle and the current angle are the same, therefore the animation does not play

brisk jewel
#

What does the prev_angle start as?

sterile skiff
#

prev_angle = angle

brisk jewel
#

That's its initial value?

#

If so, maybe try having it start as some other angle

sterile skiff
#

but if i do that, and i enter the state in that direction, every other angle will work except the one that equals the prev_angle

brisk jewel
#

It works when you go back to that direction, right?

#

Perhaps the initial value of prev_angle shouldn't be any of the actual angles, but some other value that the angle variable can't actually be

sterile skiff
#

it doesnt work

#

i think it would if we could imitate a process similar in the walk_state

#
        player.update_animation("walk")```
#
    if direction == Vector2.ZERO:
        return false

    var direction_id : int = int( round( ( direction + cardinal_direction * 0.1 ).angle() / TAU * DIR_4.size() ) )
    var new_dir = DIR_4[ direction_id ]
    
    if new_dir == cardinal_direction:
        return false

    cardinal_direction = new_dir
    return true```
#

thats the function that lets the walking animation work and loop properly

#

i think it would be possible to simplify this function because there is no prefered direction to animate

brisk jewel
#

When I'm doing something like this, I usually just have two booleans. One to tell me if the character is moving up/down and one to tell me if they're moving left/right

#

Though obviously that won't work for an 8-directional movement system

#

I'm not sure exactly how to help here, because I'm having a bit of a hard time understanding the code and intent