-
Notifications
You must be signed in to change notification settings - Fork 531
Add terrain-based footstep sound system #2941
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Leonardo-UTP
wants to merge
6
commits into
endlessm:main
Choose a base branch
from
Leonardo-UTP:issue-1095-footstep-sounds
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
9156b14
Add terrain-based footstep sound system
Leonardo-UTP f55d3ba
Fix footstep sound formatting
Leonardo-UTP aed2ed4
Add footstep sound test demo
Leonardo-UTP 3276db5
Add licenses for footstep demo sounds
Leonardo-UTP 8827854
Move footstep demo sounds to first-party assets
Leonardo-UTP 3ef0185
Rename footstep material custom data layer
Leonardo-UTP File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
assets/first_party/sounds/characters/player/FootStepsSounds/SandSound.wav
Git LFS file not shown
24 changes: 24 additions & 0 deletions
24
assets/first_party/sounds/characters/player/FootStepsSounds/SandSound.wav.import
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| [remap] | ||
|
|
||
| importer="wav" | ||
| type="AudioStreamWAV" | ||
| uid="uid://ddrhppyp6mmdf" | ||
| path="res://.godot/imported/SandSound.wav-6516c359f7d7316653f6666842461144.sample" | ||
|
|
||
| [deps] | ||
|
|
||
| source_file="res://assets/first_party/sounds/characters/player/FootStepsSounds/SandSound.wav" | ||
| dest_files=["res://.godot/imported/SandSound.wav-6516c359f7d7316653f6666842461144.sample"] | ||
|
|
||
| [params] | ||
|
|
||
| force/8_bit=false | ||
| force/mono=false | ||
| force/max_rate=false | ||
| force/max_rate_hz=44100 | ||
| edit/trim=false | ||
| edit/normalize=false | ||
| edit/loop_mode=0 | ||
| edit/loop_begin=0 | ||
| edit/loop_end=-1 | ||
| compress/mode=2 |
3 changes: 3 additions & 0 deletions
3
assets/first_party/sounds/characters/player/FootStepsSounds/StoneSound.wav
Git LFS file not shown
24 changes: 24 additions & 0 deletions
24
assets/first_party/sounds/characters/player/FootStepsSounds/StoneSound.wav.import
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| [remap] | ||
|
|
||
| importer="wav" | ||
| type="AudioStreamWAV" | ||
| uid="uid://cbxuw1d1v2w2u" | ||
| path="res://.godot/imported/StoneSound.wav-578509cf6a7f7f293a06566d5006f006.sample" | ||
|
|
||
| [deps] | ||
|
|
||
| source_file="res://assets/first_party/sounds/characters/player/FootStepsSounds/StoneSound.wav" | ||
| dest_files=["res://.godot/imported/StoneSound.wav-578509cf6a7f7f293a06566d5006f006.sample"] | ||
|
|
||
| [params] | ||
|
|
||
| force/8_bit=false | ||
| force/mono=false | ||
| force/max_rate=false | ||
| force/max_rate_hz=44100 | ||
| edit/trim=false | ||
| edit/normalize=false | ||
| edit/loop_mode=0 | ||
| edit/loop_begin=0 | ||
| edit/loop_end=-1 | ||
| compress/mode=2 |
3 changes: 3 additions & 0 deletions
3
assets/first_party/sounds/characters/player/FootStepsSounds/WoodSound.wav
Git LFS file not shown
24 changes: 24 additions & 0 deletions
24
assets/first_party/sounds/characters/player/FootStepsSounds/WoodSound.wav.import
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| [remap] | ||
|
|
||
| importer="wav" | ||
| type="AudioStreamWAV" | ||
| uid="uid://s4xqcdhebvsj" | ||
| path="res://.godot/imported/WoodSound.wav-91f3d45719b6eb24d88bf2dae0c81cd8.sample" | ||
|
|
||
| [deps] | ||
|
|
||
| source_file="res://assets/first_party/sounds/characters/player/FootStepsSounds/WoodSound.wav" | ||
| dest_files=["res://.godot/imported/WoodSound.wav-91f3d45719b6eb24d88bf2dae0c81cd8.sample"] | ||
|
|
||
| [params] | ||
|
|
||
| force/8_bit=false | ||
| force/mono=false | ||
| force/max_rate=false | ||
| force/max_rate_hz=44100 | ||
| edit/trim=false | ||
| edit/normalize=false | ||
| edit/loop_mode=0 | ||
| edit/loop_begin=0 | ||
| edit/loop_end=-1 | ||
| compress/mode=2 |
Large diffs are not rendered by default.
Oops, something went wrong.
60 changes: 60 additions & 0 deletions
60
scenes/game_elements/characters/player/components/footstep_sound.gd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # SPDX-FileCopyrightText: The Threadbare Authors | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| extends Node2D | ||
|
|
||
| @export var sound_for_material: Dictionary[String, AudioStream] | ||
|
|
||
| var _footstep_layers: Array[TileMapLayer] = [] | ||
| var _default_walk_sound: AudioStream | ||
|
|
||
| @onready var walk_sound: AudioStreamPlayer2D = %WalkSound | ||
|
|
||
|
|
||
| ## Stores the default footstep sound and caches TileMapLayers whose TileSets | ||
| ## define a "footstep_material" custom data layer. | ||
| func _ready() -> void: | ||
| _default_walk_sound = walk_sound.stream | ||
|
|
||
| var scene_root := get_tree().current_scene | ||
| var tile_map_layers := scene_root.find_children("*", "TileMapLayer", true, false) | ||
|
|
||
| for node in tile_map_layers: | ||
| var layer := node as TileMapLayer | ||
| if not layer: | ||
| continue | ||
|
|
||
| if not layer.tile_set: | ||
| continue | ||
|
|
||
| if not layer.tile_set.has_custom_data_layer_by_name("footstep_material"): | ||
| continue | ||
|
|
||
| _footstep_layers.append(layer) | ||
|
|
||
|
|
||
| ## Detects the terrain material beneath the player and plays its configured | ||
| ## footstep sound. Falls back to the default sound when no match is configured. | ||
| ## Called from the footstep frames defined in the walk animation. | ||
| func play_footstep() -> void: | ||
| if Engine.is_editor_hint(): | ||
| return | ||
|
|
||
| var current_footstep_material: String = "" | ||
|
|
||
| for layer in _footstep_layers: | ||
| var coord := layer.local_to_map(layer.to_local(global_position)) | ||
| var tile_data := layer.get_cell_tile_data(coord) | ||
|
|
||
| if not tile_data: | ||
| continue | ||
|
|
||
| var footstep_material: Variant = tile_data.get_custom_data("footstep_material") | ||
| if footstep_material is String and not footstep_material.is_empty(): | ||
| current_footstep_material = footstep_material | ||
|
|
||
| var footstep_sound: AudioStream = sound_for_material.get( | ||
| current_footstep_material, _default_walk_sound | ||
| ) | ||
|
|
||
| walk_sound.stream = footstep_sound | ||
| walk_sound.play() | ||
1 change: 1 addition & 0 deletions
1
scenes/game_elements/characters/player/components/footstep_sound.gd.uid
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://cvjpavggqssir |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All TileMapLayers will be iterated every time a footstep is played from AnimationPlayer? This doesn't sound performant at all.
Also we use several tilemap layers. I wonder what will happen if there is a "stone material" layer below a "grass material" layer. Will this algorithm play the grass material sound effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my side, I also considered the performance aspect while developing the system, mainly because of the complexity of integrating the sounds with the different tiles and TileMapLayers.
To develop the system, I first reviewed how similar situations had been handled in other parts of the project. From that review, I found some options that I could use, such as identifying specific TileMapLayers through groups or using scripts associated with the layers so that FootstepSound could recognize which ones it should check. However, these alternatives would also require manually configuring the TileMapLayers that should participate in the system.
I also took into account that scenes can have more complex TileMapLayer structures, with the terrain distributed across different layers. Because of this, the system was designed to adapt to this structure without depending on a specific TileMapLayer.
I ultimately chose the current approach as a more centralized solution. When the scene starts, the system finds the TileMapLayers whose TileSets contain a Custom Data Layer named "material" and stores them. Then, only when a footstep is triggered by the animation, those TileMapLayers are checked to identify the material at the player's position.
When multiple materials overlap, the last valid material found during that check is currently used. This was also one of the reasons why I used Fray's End for testing, due to its map structure and the more complex distribution of its TileMapLayers. This allowed me to test the system in situations involving different materials and overlapping layers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I briefly researched how to do terrain-specific footstep sounds, this is one of the ways that I came across. I also share the concern about performance but that is something that the profiler can tell us: what's the cost of iterating a (small) list of TileMapLayer nodes? Is it significant compared to the 16.6ms budget we get per 60 FPS frame? I think we should check that.
Another way you could imagine doing it is:
play()on the audiostreamplayerI actually suspect that this might be more costly for the engine because it has to deal with more absolutely enormous physics shapes for the floor layers, but this is guesswork!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for enlighten us, @wjt! Yes I agree that this should be verified with the Profiler, and against a solution that uses the physics engine. Instead of an Area2D, a RayCast2D with a single point of touch can be used. Presumably this solution will be better on performance, but it would be nice to confirm.
@Leonardo-UTP what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think it would be interesting to test the proposed RayCast2D approach and compare it with the current implementation. First, I'd like to finish the tests I'm currently doing with the existing system, and then investigate whether the RayCast2D approach is viable within Threadbare's current structure. If so, I'll try implementing it so I can compare both approaches.