Skip to content

Commit

Permalink
Merge pull request #253 from niefia/landing-audio
Browse files Browse the repository at this point in the history
Fall/Jump Landing Audio
  • Loading branch information
Phazorknight authored Sep 5, 2024
2 parents 923cec0 + 2e1546e commit 505c429
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 23 deletions.
41 changes: 39 additions & 2 deletions COGITO/CogitoObjects/cogito_player.gd
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var is_showing_ui : bool
@export var jump_sound : AudioStream
## AudioStream that gets played when the player slides (sprint + crouch).
@export var slide_sound : AudioStream
@export_subgroup ("Footstep Audio")
@export var walk_volume_db : float = -38.0
@export var sprint_volume_db : float = -30.0
@export var crouch_volume_db : float = -60.0
Expand All @@ -41,6 +42,25 @@ var is_showing_ui : bool
## the speed at which the player must be moving before the footsteps change from walk to sprint.
@export var footstep_interval_change_velocity : float = 5.2

@export_subgroup ("Landing Audio")
## Threshold for triggering landing sound
@export var landing_threshold = -2.0
## Defines Maximum velocity (in negative) for the hardest landing sound
@export var max_landing_velocity = -8
## Defines Minimum velocity (in negative) for the softest landing sound
@export var min_landing_velocity = -2
## Max volume in dB for the landing sound
@export var max_volume_db = 0
## Min volume in dB for the landing sound
@export var min_volume_db = -40
## Highest pitch for lightest landing sound
@export var max_pitch = 0.8
## Lowest pitch for hardest landing sound
@export var min_pitch = 0.7
#Setup Dynamic Pitch & Volume for Landing Audio, used to store velocity based results
var LandingPitch: float = 1.0
var LandingVolume: float = 0.8

@export_group("Movement Properties")
@export var JUMP_VELOCITY : float= 4.5
@export var CROUCH_JUMP_VELOCITY : float = 3.0
Expand Down Expand Up @@ -410,11 +430,29 @@ func _process_on_ladder(_delta):
on_ladder = false

var jumped_from_slide = false
var was_in_air = false

func _physics_process(delta):
#if is_movement_paused:
#return
# Check if the player is on the ground
if is_on_floor():
# Only trigger landing sound if the player was airborne and the velocity exceeds the threshold
if was_in_air and last_velocity.y < landing_threshold:
# Calculate the volume and pitch based on the landing velocity
var velocity_ratio = clamp((last_velocity.y - min_landing_velocity) / (max_landing_velocity - min_landing_velocity), 0.0, 1.0)
# Set the volume and pitch of the landing sound
LandingVolume = lerp(min_volume_db, max_volume_db, velocity_ratio)
LandingPitch = lerp(max_pitch, min_pitch, velocity_ratio)
# Play the landing sound
footstep_player._play_interaction("landing")
was_in_air = false # Reset airborne state
else:
was_in_air = true # Set airborne state

# Store current velocity for the next frame
last_velocity = main_velocity

if on_ladder:
_process_on_ladder(delta)
return
Expand Down Expand Up @@ -714,7 +752,7 @@ func _physics_process(delta):
footstep_player.volume_db = crouch_volume_db
elif is_sprinting:
footstep_player.volume_db = sprint_volume_db
footstep_surface_detector.play_footstep()
footstep_player._play_interaction("footstep")

can_play_footstep = false

Expand Down Expand Up @@ -861,4 +899,3 @@ class StepResult:
var diff_position: Vector3 = Vector3.ZERO
var normal: Vector3 = Vector3.ZERO
var is_step_up: bool = false

74 changes: 53 additions & 21 deletions COGITO/DynamicFootstepSystem/Scripts/footstep_surface_detector.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class_name FootstepSurfaceDetector

@export var generic_fallback_footstep_profile : AudioStreamRandomizer
@export var footstep_material_library : FootstepMaterialLibrary
@export var generic_fallback_landing_profile : AudioStreamRandomizer
@export var landing_material_library : FootstepMaterialLibrary
var last_result
var parent_rid : RID

Expand All @@ -12,48 +14,63 @@ func _ready():
parent_rid = get_parent().get_rid()
if not generic_fallback_footstep_profile:
printerr("FootstepSurfaceDetector - No generic fallback footstep profile is assigned")
if not generic_fallback_landing_profile:
printerr("FootstepSurfaceDetector - No generic fallback landing profile is assigned")


func play_footstep():
_play_interaction("footstep")

func play_landing():
_play_interaction("landing")

func _play_interaction(interaction_type: String):
var query = PhysicsRayQueryParameters3D.create(global_position, global_position + Vector3(0, -1, 0))
query.exclude = [parent_rid]
var result = get_world_3d().direct_space_state.intersect_ray(query)
if result:

last_result = result
if _play_by_footstep_surface(result.collider):
return
elif _play_by_material(result.collider):
return
#if no material, play generics
else:
_play_footstep(generic_fallback_footstep_profile)
if interaction_type == "footstep":
if _play_by_footstep_surface(result.collider, interaction_type):
return
elif _play_by_material(result.collider, footstep_material_library, generic_fallback_footstep_profile, interaction_type):
return
elif interaction_type == "landing":
if _play_by_landing_surface(result.collider, interaction_type):
return
elif _play_by_material(result.collider, landing_material_library, generic_fallback_landing_profile, interaction_type):
return

func _play_by_footstep_surface(collider : Node3D) -> bool:
func _play_by_footstep_surface(collider : Node3D, interaction_type: String) -> bool:
#check for footstep surface as a child of the collider
var footstep_surface_child : AudioStreamRandomizer = _get_footstep_surface_child(collider)
#if a child footstep surface was found, then play the sound defined by it
if footstep_surface_child:
_play_footstep(footstep_surface_child)
_play_footstep(footstep_surface_child, interaction_type)
return true
#handle footstep surface settings
elif collider is FootstepSurface and collider.footstep_profile:
_play_footstep(collider.footstep_profile)
_play_footstep(collider.footstep_profile, interaction_type)
return true
return false

func _play_by_material(collider : Node3D) -> bool:
# if no footstep surface, see if we can get a material
if footstep_material_library:
func _play_by_landing_surface(collider: Node3D, interaction_type: String) -> bool:
return _play_by_footstep_surface(collider, interaction_type)

func _play_by_material(collider: Node3D, material_library: FootstepMaterialLibrary, fallback_profile: AudioStreamRandomizer, interaction_type: String) -> bool:
if material_library:
#find surface material
var material : Material = _get_surface_material(collider)
var material: Material = _get_surface_material(collider)
#if a material was found
if material:
#get a profile from our library
var footstep_profile = footstep_material_library.get_footstep_profile_by_material(material)
var profile: AudioStreamRandomizer = material_library.get_footstep_profile_by_material(material)
#found profile, use it
if footstep_profile:
_play_footstep(footstep_profile)
if profile:
_play_footstep(profile, interaction_type)
return true
# If no specific material profile is found, play the fallback profile
_play_footstep(fallback_profile, interaction_type)
return false

func _get_footstep_surface_child(collider : Node3D) -> AudioStreamRandomizer:
Expand All @@ -64,6 +81,7 @@ func _get_footstep_surface_child(collider : Node3D) -> AudioStreamRandomizer:
return footstep_surfaces[0].footstep_profile
return null


func _get_surface_material(collider : Node3D) -> Material:
var mesh_instance = null
var meshes = []
Expand Down Expand Up @@ -143,6 +161,20 @@ func _get_surface_material(collider : Node3D) -> Material:
return mat
return null

func _play_footstep(footstep_profile : AudioStreamRandomizer):
stream = footstep_profile
play()

func _play_footstep(profile : AudioStreamRandomizer, interaction_type: String):

if interaction_type == "footstep":
stream = profile
play()

elif interaction_type == "landing":
#Setup QuickAudio landing player so that it can use its own pitch/volume parameters
var playerNode = get_parent()
var LandingVolume = playerNode.LandingVolume
var LandingPitch = playerNode.LandingPitch
var LandingPlayer = Audio.play_sound_3d(profile, false)
LandingPlayer.pitch_scale = LandingPitch
LandingPlayer.volume_db = LandingVolume
LandingPlayer.global_position = global_position
LandingPlayer.play()
3 changes: 3 additions & 0 deletions COGITO/PackedScenes/cogito_player.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,13 @@ one_shot = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.488, 0)
stream = SubResource("AudioStreamRandomizer_af0lu")
volume_db = -38.0
max_polyphony = 8
bus = &"SFX"
script = ExtResource("17_t5305")
generic_fallback_footstep_profile = ExtResource("18_mdors")
footstep_material_library = ExtResource("19_pc36t")
generic_fallback_landing_profile = ExtResource("18_mdors")
landing_material_library = ExtResource("19_pc36t")

[node name="JumpCooldownTimer" type="Timer" parent="."]
wait_time = 0.5
Expand Down

0 comments on commit 505c429

Please sign in to comment.