59 lines
1.4 KiB
GDScript
59 lines
1.4 KiB
GDScript
class_name FootstepComponent
|
|
extends Node
|
|
|
|
signal footstep_occured
|
|
|
|
@export var step_measure: float = 1.25
|
|
@export var character: CharacterBody3D
|
|
@export_node_path("AudioStreamPlayer", "AudioStreamPlayer2D", "AudioStreamPlayer3D")
|
|
var audio_player: NodePath: set = set_audio_player
|
|
|
|
var _distance_traveled: float = 0.0
|
|
var _was_in_air: bool = false
|
|
var _audio_player: Node
|
|
|
|
|
|
func _ready() -> void:
|
|
set_audio_player(audio_player)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if not is_instance_valid(character):
|
|
return
|
|
|
|
if audio_player.is_empty():
|
|
# Don't process if it isn't necessary.
|
|
return
|
|
|
|
var on_floor: bool = character.is_on_floor()
|
|
if on_floor:
|
|
if _was_in_air:
|
|
play_footstep()
|
|
_distance_traveled = 0.0
|
|
|
|
var velocity: Vector3 = abs(character.velocity) #+ (abs(character.get_platform_velocity()) if not character.velocity.is_zero_approx() else Vector3.ZERO)
|
|
velocity.y = 0.0
|
|
|
|
if velocity.is_zero_approx():
|
|
_distance_traveled = 0.0
|
|
else:
|
|
_distance_traveled += velocity.length() * delta
|
|
|
|
if _distance_traveled >= step_measure:
|
|
_distance_traveled = 0.0
|
|
play_footstep()
|
|
|
|
_was_in_air = not on_floor
|
|
|
|
|
|
func play_footstep() -> void:
|
|
footstep_occured.emit()
|
|
|
|
if is_instance_valid(_audio_player) and _audio_player.has_method(&"play"):
|
|
_audio_player.play()
|
|
|
|
|
|
func set_audio_player(new_player_path: NodePath) -> void:
|
|
audio_player = new_player_path
|
|
_audio_player = get_node_or_null(new_player_path)
|