54 lines
1.5 KiB
GDScript3
Raw Normal View History

2024-11-22 20:04:14 -07:00
class_name BallSFX extends Node3D
## Controller for ball sound effects.
const BASE_VOLUME := -36.0
const MAX_VOLUME := 3.0
const VELOCITY_ATTENUATION_SCALE := 400.0
const GRASS_PHYSICAL_LAYER := 1 << 32
const SAND_PHYSICAL_LAYER := 1 << 31
@onready var parent: GameBall = $".."
@onready var grass_sfx_player: AudioStreamPlayer3D = %GrassSFXPlayer
@onready var concrete_sfx_player: AudioStreamPlayer3D = %ConcreteSFXPlayer
@onready var sand_sfx_player: AudioStreamPlayer3D = %SandSFXPlayer
func _force_attenuated_volume() -> float:
# Attenuate volume based on impact force
return lerpf(
BASE_VOLUME,
MAX_VOLUME,
clampf(parent.linear_velocity.length_squared() / VELOCITY_ATTENUATION_SCALE, 0, 1)
)
func _play_sfx(player: AudioStreamPlayer3D) -> void:
player.volume_db = _force_attenuated_volume()
print("PLAYING: ", player, "... VOLUME: ", player.volume_db)
player.play()
func play_terrain_sfx(tex_id: int) -> void:
var player := grass_sfx_player
match tex_id:
2: # sand
player = sand_sfx_player
3: # rock
player = concrete_sfx_player
_play_sfx(player)
## Select the appropriate SFX to play based on the collision layer of the collider.
##
## We use the upper bits of the collision layer to indicate standard SFX.
func play_physical_sfx(collision_mask: int) -> void:
var player := concrete_sfx_player
if collision_mask & GRASS_PHYSICAL_LAYER:
player = grass_sfx_player
elif collision_mask & SAND_PHYSICAL_LAYER:
player = sand_sfx_player
_play_sfx(player)