How to play sound when the character is moving?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By markbatho

Hello, I want to play a footstep sound when the character is moving.
Here is my character controller script:

extends KinematicBody2D

const GRAVITY = 20
const MAX_SPEED = 200
const JUMP_HEIGHT = -600
const ACCELERATION = 30
const UP = Vector2(0, -1)
var motion = Vector2()
var is_crouching = false

func _ready():
	$Crickets.play()

func _physics_process(delta):
	motion.y += GRAVITY
	var friction = false
	
	if Input.is_action_pressed("ui_right"):
		if not is_crouching:
			motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
			$Sprite.flip_h = false
			$Sprite.play("Run")
		else:
			motion.x = min(motion.x+ACCELERATION, MAX_SPEED/2)
			$Sprite.flip_h = false
			$Sprite.play("CrouchingWalk")
	elif Input.is_action_pressed("ui_left"):
		if not is_crouching:
			motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
			$Sprite.flip_h = true
			$Sprite.play("Run")
		else:
			motion.x = max(motion.x-ACCELERATION, -MAX_SPEED/2)
			$Sprite.flip_h = true
			$Sprite.play("CrouchingWalk")
	else:
		if not is_crouching:
			$Sprite.play("Idle")
		else:
			$Sprite.play("Crouching")
		friction = true
	
	if is_on_floor():
		if Input.is_action_just_pressed("ui_down"):
			is_crouching = true
			$CollShapeTop.disabled = true
			$Sprite.play("Crouching")
		elif Input.is_action_just_pressed("ui_up"):
			if not is_crouching:
				motion.y = JUMP_HEIGHT
			else:
				is_crouching = false
				$CollShapeTop.disabled = false
				$Sprite.play("Idle")
		if friction == true:
			motion.x = lerp(motion.x, 0, 0.9)

            # I want to play the sound when character is on the floor and moving on the ground, not jumping.
		if motion.x >= 1 || motion.x <= -1:
			$Footstep.play()
		else:
			$Footstep.stop()
	else:
		if motion.y < 0:
			$Sprite.play("Jump")
		else:
			$Sprite.play("Fall")
		if friction == true:
			motion.x = lerp(motion.x, 0, 0.05)
	motion = move_and_slide(motion, UP)

The problem is that when I press the arrow keys sound starts to playing, but not the whole sound… It starting over and over again… $Footstep is a AudioStreamPlayer2D with a footstep sound(47s ogg file).

:bust_in_silhouette: Reply From: markbatho

Okay, I played a little with the code…
This is the modified version:

extends KinematicBody2D

const GRAVITY = 20
const MAX_SPEED = 200
const JUMP_HEIGHT = -600
const ACCELERATION = 30
const UP = Vector2(0, -1)
var motion = Vector2()
var is_crouching = false

func _ready():
	$Crickets.play()

func _physics_process(delta):
	motion.y += GRAVITY
	var friction = false
	
	if Input.is_action_pressed("ui_right"):
            # Here is the sound, played when player is on the ground:
		if is_on_floor():
			if not $Footstep.is_playing():
				$Footstep.play()
		if not is_crouching:
			motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
			$Sprite.flip_h = false
			$Sprite.play("Run")
		else:
			motion.x = min(motion.x+ACCELERATION, MAX_SPEED/2)
			$Sprite.flip_h = false
			$Sprite.play("CrouchingWalk")
	elif Input.is_action_pressed("ui_left"):
            # Here is the sound, played when player is on the ground:
		if is_on_floor():
			if not $Footstep.is_playing():
				$Footstep.play()
		if not is_crouching:
			motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
			$Sprite.flip_h = true
			$Sprite.play("Run")
		else:
			motion.x = max(motion.x-ACCELERATION, -MAX_SPEED/2)
			$Sprite.flip_h = true
			$Sprite.play("CrouchingWalk")
	else:
            # Stop when player is idle so not moving
		$Footstep.stop()
		if not is_crouching:
			$Sprite.play("Idle")
		else:
			$Sprite.play("Crouching")
		friction = true
	
	if is_on_floor():
		if Input.is_action_just_pressed("ui_down"):
			is_crouching = true
			$CollShapeTop.disabled = true
			$Sprite.play("Crouching")
		elif Input.is_action_just_pressed("ui_up"):
                    # And play the jumping sound:
			if $Footstep.is_playing():
				$Footstep.stop()
			if not is_crouching:
				$Jump.play()
				motion.y = JUMP_HEIGHT
			else:
				is_crouching = false
				$CollShapeTop.disabled = false
				$Sprite.play("Idle")
		if friction == true:
			motion.x = lerp(motion.x, 0, 0.9)
	else:
		if motion.y < 0:
			$Sprite.play("Jump")
		else:
			$Sprite.play("Fall")
		if friction == true:
			motion.x = lerp(motion.x, 0, 0.05)
	motion = move_and_slide(motion, UP)

Any idea for play a sound when the player is in the aire (when jump) and touch the floor? Can you use the above script.

Jalkhov | 2020-06-20 02:21

It worked for me thank you very much.

Shazaka | 2020-10-07 04:49