|
|
|
 |
Attention |
Topic was automatically imported from the old Question2Answer platform. |
 |
Asked By |
Lothrinn |
Hello !
I’m making a game where the player has to collect “light fragments” and bring them to an altar in order to complete the level. I have a problem where the “AltarLitUp” animation plays on loop when my player enters its detection area with all 10 fragments even though the “AltarLitUp” animation isn’t set on loop. I would like to make it so it stops at the last frame of the animation (when the altar is completely lit). Could someone please help me ? I’ve tried using AnimationPlayer.stop()
and _on_animation_finished
but nothing seems to work.
Here’s my code :
extends Node2D
onready var animationPlayer = $AnimationPlayer
var player : Player
func _ready() -> void:
set_process(false)
func _on_Altar_body_entered(body):
if not body is Player:
return
player = body
if player == body:
set_process(true)
func _process(delta: float):
if LightFragmentsCollected.current_score == 10:
animationPlayer.play("AltarLitUp")
else:
animationPlayer.play("AltarIdle")
|
|
|
 |
Reply From: |
njamster |
It loops because you’re calling play()
in _process
, i.e. every frame! That instruction is ignored if the specified animation is already playing, but once the animation finishes it’s processed again, thus the animation loops infinitely. Stopping it wont help because the animation will be instantly restarted the next time _process
is called.
If the altar is supposed to light up once the player enters it’s area with enough fragments, you can simply do this:
func _on_Altar_body_entered(body):
if not body is Player: return
if LightFragmentsCollected.current_score == 10:
animationPlayer.play("AltarLitUp")
If you want this to happen only once, add a boolean:
var already_entered = false
func _on_Altar_body_entered(body):
if not body is Player: return
if not already_entered:
already_entered = true
if LightFragmentsCollected.current_score == 10:
animationPlayer.play("AltarLitUp")
If you really want the altar to light up regardless of where the player is, as long as the player entered the area once before and has collected enough fragments:
var already_entered = false
func _ready() -> void:
set_process(false)
func _on_Altar_body_entered(body):
if not body is Player: return
set_process(true)
func _process(delta: float):
if LightFragmentsCollected.current_score == 10:
if not already_entered:
already_entered = true
animationPlayer.play("AltarLitUp")
else:
animationPlayer.play("AltarIdle")
On a side note, your if-condition is pointless: player == body
will always be true, if you set player = body
the line before. I’m not sure what you’re trying to do there.
Hey, thank you for your quick answer, it works ! 
I made my if condition player == body
yesterday when I was trying to solve another problem I’m having where I was trying to make the player character plays its “LevelComplete” animation when the Enter key was pressed once inside the area of the altar and all fragments collected (still doesn’t work right now but I’ll figure it out somehow, maybe with signals), I didn’t realize it was pointless but it makes sense !
Lothrinn | 2020-05-06 12:04
|
|
|
 |
Reply From: |
jasperbrooks79 |
You can make it so, maybe been said, add another variable, HasPlayedOnce, set it to false, then make sure, condition for playing is what triggers animation and, also HasPlayedOnce = FALSE . . Then, when you play it, from code, also SET HasPlayedOnce to TRUE . .

Only play, if animation - triggered AND HasPlayedOnce = false <3
Hey, thank you for your answer !
Yes, the top comment of this question has answered my question and now everything works. I also used this method to make the player character play its “Level Complete” animation when it is in the area of the altar and has collected all fragments 
Lothrinn | 2020-05-06 15:14
|
|
|
 |
Reply From: |
jasperbrooks79 |
Or, you can make an integer, called ’ TimesPlayed ', start by setting it to ZERO, then WHEN animation is played, set it to 1, and ADD condition ( play IF Timesplayed LESS than 1 ) . . <3