im a beginner at programming in godot
lets say my character is in a default idle mode where their default idle animation plays, and i want them to sit after a one shot timer node times out or after an amount of default animation loops have looped, with a non looping animation of trying to sit and then a looping animation of sitting
ive thought about it and tried different coding ways for hours and none worked
the problem mainly was that either if i put different animations in different statements of ifs, or if i put the code of the timer in them, because they constantly check for the conditions and constantly give the statements, the animations would not get to each other as expected and the timer would restart before going all the way.
or either with boolean variables is that for some reason even they wont stop the if statements from constantly working
and even while trying out signals as a way to check when the timer has ran out, or when the non looping animation has finished, again the if functions go constanly off and ruin everything
i deleted the codes that didnt work but this ones my last try:
Blockquote
var is_idle := true
var times := 0
Blockquote
if direction == 0
is_idle = true
else:
is_idle = false
Blockquote
if is_idle:
character.play(“character_idle”)
_on_character_animation_looped(“kitty_idle”)
if times >= 5:
character.play(“character_too_idle”)
times =0 _on_character_animation_finished(“character_too_idle”)
elif is_idle == false:
character.play(“character_run”)
Blockquote #signals:
func _on_character_animation_finished(anim_name) → void:
if anim_name == “character_too_idle”:
return character.play(“character_wait”)
# by replacing this code after return with print(“sth”), i also found out that it seems like this one is the problem and there will be infinite "sth"s getting printed but i dont know why
func _on_character_animation_looped(anim_name2) → void:
if anim_name2 == “character_idle”:
times += 1
You can queue animations for the animation_player so you make the sit down and sitting_idle animation play one after another.
You could try something like this, using some simple states. It’s not very clean, just to give you an idea:
var sit_down_time = 10 # will sit down after 10 seconds of idling
var state = "Idle"
var idle_timer = 0
func _process(delta: float) -> void:
if direction: # if moving
if state != "Moving":
state = "Moving"
idle_timer = 0 # reset timer
animation_player.play("character_run") # play run animation
else: # if idling
if state != "Sitting": # if not sitting yet
idle_timer += delta # advance timer
if sit_down_time <= idle_timer: # if timer reached "sit down" time
state = "Sitting"
animation_player.play("character_sit_down") # play sit down anim
animation_player.queue("character_idle_sitting") # queue looped sit anim
elif state != "Idle": # if it isn't time to sit down yet
state = "Idle"
animation_player.play("character_idle") # play normal idle anim
wow, thats cool!
wish something like this could have come into my mind but i can learn in this way as well so…great!!
thanks! even though i havent tried it yet, now i have the idea of what to do and learned a lot!
sorry for bothering again…i did the exact same code as you said with the name of my own sprites to show myself how the code works but when i start the game the character doesnt sit after the specified amount of time and if i move, it will get stuck in the moving animation…can you help please?
Sorry, I didn’t actually test it…
Could you post your code so I can take a look?
(Use the </> icon here when you paste it to keep it readable please)
its literally the same exact code but here you go:
p.s: also thanks for spending your time on me
<
# Variables for different states of the character
var time_before_wait := 5
var state = "idle"
var idle_timer = 0
# Define the current state
if direction != 0:
if state != "moving":
state = "moving"
idle_timer = 0
character.play("character_run")
elif direction == 0:
if state != "sitting":
idle_timer += delta
if time_before_wait <= idle_timer:
state = "sitting"
character.play("character_sitting")
character.queue("character_waiting")
elif state != "idle":
state = "idle"
character.play("character_idle")>
No problem
Change the var state = "idle" line at the top to this: var state = ""
so it starts as empty and changes to “idle” when you start the game.
Other than that the code itself seem to work for me. If you add the print lines like this you can test if the states are being changed correctly.
It does print “sitting” for me after five seconds, and also prints “idle” when I release the movement keys, doesn’t get stuck in moving state.
func _process(delta):
direction = Input.get_axis("ui_left", "ui_right")
# Define the current state
if direction != 0:
if state != "moving":
state = "moving"
print("moving") # <- added print line
idle_timer = 0
character.play("character_run")
elif direction == 0:
if state != "sitting":
idle_timer += delta
if time_before_wait <= idle_timer:
state = "sitting"
print("sitting") # <- added print line
character.play("character_sitting")
character.queue("character_waiting")
elif state != "idle":
state = "idle"
print("idle") # <- added print line
character.play("character_idle")
Do they get printed for you correctly? If so maybe it’s only the animations don’t play?
Oh wait, are you using animated sprites? I don’t think those have the queue method… I thought you were using animation player.
Then I guess you could play two animations after each other by creating a function like this for example:
thanks ill try all of these!
can i just know what changing the “idle” to " " would do?
because as we know, the state var is just a variable we created that shows the state of the character for our ease of coding and understanding the code in the future and nothing more i assume
ok so i tried it and i get infinite "moving"s getting printed in the console…
its as if whatever i write under the if statement and add an animated sprite at the end, it will just do them forever for some reason…
oh yea also…i have _physics_process function at the top instead of _process idk if the problem is because of that
It’s not just for that. It’s there so when we switch states the code for switching states only runs once.
For example the sit down animation will only runs once when you switch to siting state. Otherwise the sit down anim would be played every frame while sitting…
Same reason to change “idle” to “”.
If you declare the state variable as “idle”, then this if statement will be false at the beginning of the game and the character.play("character_idle") won’t be called and it won’t play the idle anim at the beginnning.
elif state != "idle":
state = "idle"
character.play("character_idle")
I don’t know how…
When the code runs the first time you set state to “moving” then the if statement will be false and it shouldn’t run anymore (as I said in the previous post). It shouldn’t print infinitely…
if state != "moving":
state = "moving"
# rest of the code
at first when i start the game, the character is in the idle state and i get infinite "idle"s getting printed, then when i move they turn into “moving” and when i stop and do not press any key, they, plus the animation stay at the moving state
also, is using _physics_process instead of _process the problem?
becuase ive used that to have some movements and collisions on the character body as well
it doesnt, though funny enough, if i set time_before_wait to 0 just to see if there are any flaws in the sitting process, there will be a billion "sitting"s and the animation of sitting will play over and over
i tried setting a boolean var for it to happen only one time but its as if the if statement ignores a boolean check condition and just takes it as a true and runs over and over
Well I don’t know what’s the issue.
There should be no need for a boolean, that’s why this check is there already if state != "sitting": Once you set the state to “sitting” this will be false and shouldn’t run anymore.
This should be this: one_time = false. If you have that typo in your code too then that might be the problem.
But once the timer reaches sitting time, the state will be set to “sitting” and this line if state != "sitting": will be false and that whole part of the code should not run anymore, so adding an extra boolean there shoulnd’t make a difference
yea that was typo here…
but as a beginner, knowing delta means the amount of time since last frame and not an actual second i wonder if the “idle_timer += delta” would actually count in seconds…
also, i printed the idle_number on the console to see if it actually changes when idle…
and the amount is constantly 0.01666666666667 while it should change every second as you said to at some point hit time_before_wait
is there a reason for that?..