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
Add interaction sounds to BaseButton (customizable via theme) #1472
Comments
|
See also godotengine/godot#3608. |
Thancc. cool and good. However though, there is a disadvantage you have to beware:
well, I guess, maybe an |
As long as you don't have thousands of buttons instantiated at the same time, there shouldn't be a problem, right? |
at least it works really well. If the workflow is simply at only one way form of a UI in this node or anything simple and not complicated, this should not be a problem. but yeah. my game workflow is like above, New nodes that will instantiated & freed. And I have alot. perhaps by having |
I worked around this in godot-mdk by adding a custom class that extends Button and instantiating it in my scenes using the editor instead of using Button. Here's a more generic example: # Save this script, then add MyButton nodes instead of Button using the Create New Node dialog.
extends Button
class_name MyButton
## Called when the button is pressed.
func _pressed():
# This assumes you have a Sound singleton designed to play sounds with polyphony:
# https://github.com/Calinou/godot-mdk/blob/master/autoload/sound.gd
Sound.play(self, preload("res://button_click.wav")) The |
As the theme guy on the team I fully support that controls should have an inherent ability to produce focus and interaction sounds, and that it should be customizable with a theme. It's not too hard to work around with nodes, but it's an unnecessary complication for getting your game that polished feel. I will gladly work on this. |
Button
customizable via theme
Button
customizable via theme
One more option (for 4.0-dev): extends Button
class_name MyButton
var _allow_focus_sfx := true
func _init() -> void:
focus_entered.connect(_on_focus_entered)
func _input(event: InputEvent) -> void:
if !is_visible_in_tree() || !has_focus():
return
if event.is_action_pressed('ui_accept'):
if disabled:
SFX.play('gui_error.wav')
else:
SFX.play('gui_accept.wav')
func grab_focus_no_sfx() -> void:
_allow_focus_sfx = false
grab_focus()
_allow_focus_sfx = true
func _on_focus_entered() -> void:
if _allow_focus_sfx:
SFX.play('gui_focus.wav') |
@dalexeev that doesn't work for mouse right clicks |
Note that this will probably require something analogous to SceneTreeTimer/SceneTreeTween to be implemented. A SceneTreeAudioStreamPlayer should allow polyphonic audio playback without creating any nodes, so that using things like (This is also useful in game logic if you want to avoid the issue where freeing a node stops its audio playback. However, we'd need to add positional variants in this case as well, and you would most likely not be able to change their position after creating them.)
It should work with right-clicks if the button has the appropriate click mask. Buttons should not play a sound if clicked with a button that doesn't actually press them, so it's expected that by default, right-clicking shouldn't play a sound. |
@Calinou it doesn't. it only tends to play the focus sound with the mouse. try it
|
@Shadowblitz16 Sorry, I forgot to mention that this class was only implemented for keyboard control. Mouse support requires other changes. For example like this: Codeextends Button
class_name MyButton
var _allow_focus_sfx := true
func _init() -> void:
focus_entered.connect(_on_focus_entered)
button_down.connect(_on_button_down)
pressed.connect(_on_pressed)
func _gui_input(event: InputEvent) -> void:
if disabled:
if event.is_action_pressed("ui_accept") or (
event is InputEventMouseButton
and event.button_index == MOUSE_BUTTON_LEFT
and event.is_pressed()):
SFX.play("gui_error.wav")
func grab_focus_no_sfx() -> void:
_allow_focus_sfx = false
grab_focus()
_allow_focus_sfx = true
func _on_focus_entered() -> void:
if _allow_focus_sfx and not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
SFX.play("gui_focus.wav")
func _on_button_down() -> void:
SFX.play("gui_focus.wav")
func _on_pressed() -> void:
if toggle_mode:
if button_pressed:
SFX.play("gui_enabled.wav")
else:
SFX.play("gui_disabled.wav")
else:
SFX.play("gui_accept.wav") |
@YuriSizov How do you envision the audio theme items in terms of structure? I'm asking because I wonder how we could expose a way to set generic "hover", "focus", "pressed" sounds that work across the entire theme, without requiring users to override them on individual classes. However, if users wish to override the interaction sounds on a specific control, they should be able to do so. Could this work in a manner similar to the Default Font top-level Theme property? |
@Calinou I'm not a fan of this idea. The default font works because we can decide to use it as a fallback based on the resource type. What you propose is that we add special resolution logic based on the resource type AND the name of a theme item. We don't really have a very consistent theme item naming convention and it would make the whole thing string-reliant. So for now I'd focus on implementing the core system, having audio as a theme item type, making it work, figuring out how it must work. The hard part is figuring out how the audio stuff is going to be configured. Should we allow for positional audio or should it be position-less? How do we configure the bus? Would it be a part of some theme audio resource or a setting on the theme resource? Or a global setting per project? Having some kind of fallback system can be added later, if we truly need it. Way after we ship the initial feature. |
7.5 years after originally proposing this feature, I have a working proof of concept: https://github.com/Calinou/godot/tree/add-theme-audio-items Testing project: control_gallery.zip I couldn't figure out how to play audio without creating nodes1, so I added a helper method to SceneTree that creates a temporary top-level internal node (similar to what godotengine/godot#79599 does). The node is automatically freed once audio playback is finished. Multiple nodes may be created at once, which implicitly allows for polyphony (including with different, unrelated AudioStreams). Using an AudioStreamRandomizer resource should work too, if you want to add some variation to UI sounds. From a performance standpoint, creating nodes is probably not too bad since you're unlikely to have more than 5 active UI audio sources at a given time. (This is especially the case if you stick to WAV, as recommended for short audio files.) Footnotes
|
Amazing work!
Well, that's a bummer. I think this should be resolved first, we need to be able to do the playback directly with the server, at least for the non-positional audio (which is what the UI sfx would likely be). Maybe @ellenhp can help us figure out how feasible it would be to implement? |
I made further progress in my branch: https://github.com/Calinou/godot/tree/add-theme-audio-items simplescreenrecorder-2023-08-07_11.34.57.mp4Sounds from https://github.com/redeclipse/sounds. There are still some things to iron out (specifically regarding the inspector and |
Is there a pull request for this in godot master? This is a must feature. |
Not yet, as my branch still has some work left to do (check the |
That's sad to hear. Maybe this comes to the 4.4 then? For the video it was looking very promising, keep the good work. I will leave it out here as I don't have much to contribute to the proposal, but imo audio theme UI is brilliant suggestion that I strongly support. |
Describe the project you are working on:
I am working on a match 3 game
Describe the problem or limitation you are having in your project:
For all the button presses I have to manually code a sound to be played by creating a global sound manager whenever a button is pressed
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Add sound to be played on button pressed
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
Sorry, I am a beginner in godot and game development, I don't know how to impplement it.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
I think this is used for every button in every game made.
Is there a reason why this should be core and not an add-on in the asset library?:
Again, because there are always sounds on button presses
The text was updated successfully, but these errors were encountered: