First project Here I just wanted to add hearts and play an animation when you lose them, i have a node2d with 3 animated sprites children one for each heart, when I collide with an enemy i dont lose a heart as it doesnt play the animation and im not sure why. Im new so if its for a stupid reason i apologise
#Animation not playing
36 messages · Page 1 of 1 (latest)
Try putting your debug print()s at the start of takeheart(), before the 'if' statement runs at all. If it never shows up even when it's out of any conditionals, that'll mean the function isn't being triggered at all, which might mean there's a problem with the collision between the player and the enemy that's worth investigating.
(Also, optimization tip in general: I think the way that it is now, it's going to always take all three of them when it runs, since 3 bringing u down to 2 doesn't prevent it for checking for 2 right after. Try looking into 'match' statements to make the code more solid!)
The function is being triggered, in the 5th image with the game running if you zoom into the console it says reached and it's printed the hearts var
Ooo I'll look into it thank you very much
It just for some reason don't run the .play code
Ah, then you might have a problem with the animation...
are other animations in your project working? compare them and see if there's any obvious things missing from the setup
like, i'm from GamemakerStudio country, and a common error back there is not changing the default FPS for an imported animation, causing it to play super disorientingly fast. See if there's any basic steps you might have overlooked in bringing the images into the project
Okay thank you will do, my other animations work completely fine so I'm really confused as to why this isn't working
I’m not sure if this is really helpful but I’m curious what folks think about this as an alternate function? Newer to programming but I’m curious if this would be a logical refactor
func takeHearts() hearts -= 1 match hearts: 2: three.play(“Lose”) 1: second.play(“Lose”) 0: first.play(“Lose”)
Also, I may be missing it but I don’t see an AnimPlayer in your scene - how are you doing the animation? (I’ve only really used Animation Player or doing it manually with code, still so much to learn 😄 )
It becomes sort of the same thing as doing it with if statements and it works fine for a set amount of hearts. However it doesn't scale well if you could for example gain hearts. I think having a collection of hearts and then popping the last one could work as well.
Something like this (pseudocode):
export var hearts: Array[Heart] = []
...
func takeHearts():
var heart = hearts.pop_back();
if heart == null:
return
heart.play("Lose")
...
This would scale with N amount of hearts without having to rewrite the logic each time you add or remove a heart in the scene and would adapt to gaining hearts in game.
I'm using animated sprites, so the each node had the same lose animation
All I'm doing is using .play to play that animation but it doesn't
You have 3 debugger errors, have you checked if they might be related in any way?
You also call HeartsManager, is that an AutoLoad named HeartsManager that points to Hearts?
One spontaneous guess is that you have both Hearts as an actual node in the main tree, and Hearts as an autoloaded node (HeartsManager). If that would be so, both would load and the HeartsManager would probably would animate fine, but since the Heart node also exists it would be put at the same spot as the HeartsManager, render 6 hearts (3 on top of another 3), where only 3 of them would animate. Can it be that the Hearts node is rendered on top of the HeartsManager node? (If both of them are the Hearts scene)
Hi yeah I checked that and it was just on body entered parameters have not been used so it wasn't related
Yes that is
Ohhhh is that how that works???
If I have an auto loaded scene does that scene automatically become apart of my game scene ?
Yes!
I was only automating it so I could access the functions from different scripts
Ohhhh okay I'll check that out then that's most likely it thank you
Feel free to come back if it didn't work. I created a copy of your setup (sort of) with an autoload and it worked fine with the code you have. So my best guess is that the animation is just hidden by the other layer on top of it. Good luck! 🙂
Okay that makes the most sense
If I delete the hearts scene from my tree can I make the auto load scene apart of my canvas layer?
I'm assuming the node will be invisible so I'm not sure how that would work
The node will be appended as it is, so visually as well, just at the bottom of the tree (i think)
What you could do is make the HeartsManager (autoload) a purely code based node and keep your Hearts node.
In the HeartsManager you could then emit a signal when the function is called (take_heart) and listen for the signal in the Hearts node.
It would be something like
hearts_manager.gd
extends Node
signal heart_taken()
func take_heart():
heart_taken.emit()
hearts.gd (your existing UI node)
...
func _ready():
HeartsManager.heart_taken.connect(_on_heart_taken)
func _on_heart_taken():
call the function here to animate, or do it directly
This way you could listen for the heart_taken signal in other components, for example if you want to flash when taking damage or other fun stuff.
okay i just tried deleting the hearts scene but once thats gone theres no autoloaded hearts scene so idk what to do from here
sorry to clarify heartsmanager is the name for the hearts script thats in the autoload section
Have you tried adding a button to your hearts scene to manually trigger the animation? This way you could runt that individual scene and test the takeHeart() function individually. Bind the pressed to takeHeart in _ready, then launch that scene alone and test it
So the fix I found for it was to just remove the global node, and just attach the hearts scene to a group and then retrieve the function in my enemy zone from the group using gettree get scenes in group method
Idk why it didn't work the normal way but I'm assuming it's an issue to Do with the path of the node or something
Because it wasn't null or anything and it was displaying the correct animation labels but it just wouldn't play it
But this workaround is okay