2D platformer footsteps sound effect logic - success!
I've been trying to add a footsteps sound effect to my player that will only play when he's walking, and was going to post this as a question to the group, but in the course of explaining my steps below, I was able to analyze the problem better, and now I have it working perfectly!
I'll start by saying the basis for this player controller is not mine. I believe it mostly comes from an official Godot tutorial... but now I understand it :-)
So in the game, my player character jumps, walks and falls. I have a 10-second clip of the footsteps sound, and it's set to play as a loop. Here's the progression of my attempts to get the footsteps sound to always play when walking, and never play when stopped, jumping or falling :
Attempt #1: Simply play the sound when left or right buttons are pressed. (I was so naive...)
Results: Triggered the sample every frame, of course! Which sounds like a Geiger counter.
Attempt #2: Play the sample when left or right buttons are JUST pressed (so it's only triggered once instead of re-triggering every frame while a walk button is held down).
Results: Kinda works! But we still hear it during jumps and falls...
Attempt #3: Only play the sample when left or right buttons are JUST pressed AND my character is_on_floor. Also added "
$WalkSound.stop" to my "jump" code, to completely remove the walking sound during jumps.
Results: Almost there! But there's one problem remaining now... at the end of a jump or fall, if I've kept my finger on the same walk button throughout the duration of a jump, and then I land, the sound never re-triggers, because it's only checking if walk buttons are JUST pressed. So after a landing like that, I'm walking without footsteps again...
Attempt #4: Finally, I tried brute-forcing it. I created a "walking" boolean. I said, "If I'm walking AND I'm on the floor AND $WalkingSound is NOT already playing, then play it. Also, if "walking" stops being true, or I'm not on the floor, then stop playing it. And if $WalkingSound is already playing, don't trigger it again.
Results: It worked!
Here's the Player scene:
So Player is a KinematicBody that has a CollisionShape2D, a Sprite, and two AudioStreamPlayers: WalkSound and Jumpsound.
The full player controller script is attached. Hope it helps somebody else who gets stuck on this! Also, I'm betting there's a more elegant solution than my brute-force, very explicit solution... if you know of anything like that, I'd love to know how it would be done!