Add UI click sounds (#22410)

* Add UI click sounds

* tweaks

* Significant cleanup

* Audio options and numerous fixes

* Fix the remaining UI elements

* new click sound

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
This commit is contained in:
metalgearsloth
2023-12-29 15:43:36 +11:00
committed by GitHub
parent 5f7e92a2d7
commit 4023134cf0
19 changed files with 179 additions and 21 deletions

View File

@@ -0,0 +1,98 @@
using Content.Shared.CCVar;
using Robust.Client.Audio;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controllers;
using Robust.Shared.Audio.Sources;
using Robust.Shared.Configuration;
namespace Content.Client.Audio;
public sealed class AudioUIController : UIController
{
[Dependency] private readonly IAudioManager _audioManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IResourceCache _cache = default!;
private float _interfaceGain;
private IAudioSource? _clickSource;
private IAudioSource? _hoverSource;
private const float ClickGain = 0.25f;
private const float HoverGain = 0.05f;
public override void Initialize()
{
base.Initialize();
/*
* This exists to load UI sounds outside of the game sim.
*/
// No unsub coz never shuts down until program exit.
_configManager.OnValueChanged(CCVars.UIClickSound, SetClickSound, true);
_configManager.OnValueChanged(CCVars.UIHoverSound, SetHoverSound, true);
_configManager.OnValueChanged(CCVars.InterfaceVolume, SetInterfaceVolume, true);
}
private void SetInterfaceVolume(float obj)
{
_interfaceGain = obj;
if (_clickSource != null)
{
_clickSource.Gain = ClickGain * _interfaceGain;
}
if (_hoverSource != null)
{
_hoverSource.Gain = HoverGain * _interfaceGain;
}
}
private void SetClickSound(string value)
{
if (!string.IsNullOrEmpty(value))
{
var resource = _cache.GetResource<AudioResource>(value);
var source =
_audioManager.CreateAudioSource(resource);
if (source != null)
{
source.Gain = ClickGain * _interfaceGain;
source.Global = true;
}
_clickSource = source;
UIManager.SetClickSound(source);
}
else
{
UIManager.SetClickSound(null);
}
}
private void SetHoverSound(string value)
{
if (!string.IsNullOrEmpty(value))
{
var hoverResource = _cache.GetResource<AudioResource>(value);
var hoverSource =
_audioManager.CreateAudioSource(hoverResource);
if (hoverSource != null)
{
hoverSource.Gain = HoverGain * _interfaceGain;
hoverSource.Global = true;
}
_hoverSource = hoverSource;
UIManager.SetHoverSound(hoverSource);
}
else
{
UIManager.SetHoverSound(null);
}
}
}

View File

@@ -1,15 +1,18 @@
using Content.Shared.Audio;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Robust.Client.GameObjects;
using Robust.Shared;
using Robust.Shared.Audio;
using Robust.Client.Audio;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using AudioComponent = Robust.Shared.Audio.Components.AudioComponent;
namespace Content.Client.Audio;
public sealed partial class ContentAudioSystem : SharedContentAudioSystem
{
[Dependency] private readonly IAudioManager _audioManager = default!;
[Dependency] private readonly IResourceCache _cache = default!;
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
// Need how much volume to change per tick and just remove it when it drops below "0"
private readonly Dictionary<EntityUid, float> _fadingOut = new();
@@ -32,6 +35,7 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
public const float AmbienceMultiplier = 3f;
public const float AmbientMusicMultiplier = 3f;
public const float LobbyMultiplier = 3f;
public const float InterfaceMultiplier = 2f;
public override void Initialize()
{

View File

@@ -394,7 +394,7 @@ namespace Content.Client.Construction.UI
if (IsAtFront)
{
WindowOpen = false;
_uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Pressed = false; // This does not call CraftingButtonToggled
_uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.SetClickPressed(false); // This does not call CraftingButtonToggled
}
else
_constructionView.MoveToFront();
@@ -402,7 +402,7 @@ namespace Content.Client.Construction.UI
else
{
WindowOpen = true;
_uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.Pressed = true; // This does not call CraftingButtonToggled
_uiManager.GetActiveUIWidget<GameTopMenuBar>().CraftingButton.SetClickPressed(true); // This does not call CraftingButtonToggled
}
}

View File

@@ -74,6 +74,19 @@
<Label Name="LobbyVolumeLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
<Label Text="{Loc 'ui-options-interface-volume'}" HorizontalExpand="True" />
<Control MinSize="8 0" />
<Slider Name="InterfaceVolumeSlider"
MinValue="0"
MaxValue="100"
HorizontalExpand="True"
MinSize="80 0"
Rounded="True" />
<Control MinSize="8 0" />
<Label Name="InterfaceVolumeLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
<Label Text="{Loc 'ui-options-ambience-max-sounds'}" HorizontalExpand="True" />
<Control MinSize="8 0" />

View File

@@ -2,13 +2,10 @@ using Content.Client.Audio;
using Content.Shared.CCVar;
using Robust.Client.Audio;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Range = Robust.Client.UserInterface.Controls.Range;
@@ -39,6 +36,7 @@ namespace Content.Client.Options.UI.Tabs
AmbienceVolumeSlider.OnValueChanged += OnAmbienceVolumeSliderChanged;
AmbienceSoundsSlider.OnValueChanged += OnAmbienceSoundsSliderChanged;
LobbyVolumeSlider.OnValueChanged += OnLobbyVolumeSliderChanged;
InterfaceVolumeSlider.OnValueChanged += OnInterfaceVolumeSliderChanged;
LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled;
RestartSoundsCheckBox.OnToggled += OnRestartSoundsCheckToggled;
EventMusicCheckBox.OnToggled += OnEventMusicCheckToggled;
@@ -59,6 +57,7 @@ namespace Content.Client.Options.UI.Tabs
AmbientMusicVolumeSlider.OnValueChanged -= OnAmbientMusicVolumeSliderChanged;
AmbienceVolumeSlider.OnValueChanged -= OnAmbienceVolumeSliderChanged;
LobbyVolumeSlider.OnValueChanged -= OnLobbyVolumeSliderChanged;
InterfaceVolumeSlider.OnValueChanged -= OnInterfaceVolumeSliderChanged;
base.Dispose(disposing);
}
@@ -67,6 +66,11 @@ namespace Content.Client.Options.UI.Tabs
UpdateChanges();
}
private void OnInterfaceVolumeSliderChanged(Range obj)
{
UpdateChanges();
}
private void OnAmbientMusicVolumeSliderChanged(Range obj)
{
UpdateChanges();
@@ -120,6 +124,7 @@ namespace Content.Client.Options.UI.Tabs
_cfg.SetCVar(CCVars.AmbienceVolume, AmbienceVolumeSlider.Value / 100f * ContentAudioSystem.AmbienceMultiplier);
_cfg.SetCVar(CCVars.AmbientMusicVolume, AmbientMusicVolumeSlider.Value / 100f * ContentAudioSystem.AmbientMusicMultiplier);
_cfg.SetCVar(CCVars.LobbyMusicVolume, LobbyVolumeSlider.Value / 100f * ContentAudioSystem.LobbyMultiplier);
_cfg.SetCVar(CCVars.InterfaceVolume, InterfaceVolumeSlider.Value / 100f * ContentAudioSystem.InterfaceMultiplier);
_cfg.SetCVar(CCVars.MaxAmbientSources, (int)AmbienceSoundsSlider.Value);
@@ -143,6 +148,7 @@ namespace Content.Client.Options.UI.Tabs
AmbienceVolumeSlider.Value = _cfg.GetCVar(CCVars.AmbienceVolume) * 100f / ContentAudioSystem.AmbienceMultiplier;
AmbientMusicVolumeSlider.Value = _cfg.GetCVar(CCVars.AmbientMusicVolume) * 100f / ContentAudioSystem.AmbientMusicMultiplier;
LobbyVolumeSlider.Value = _cfg.GetCVar(CCVars.LobbyMusicVolume) * 100f / ContentAudioSystem.LobbyMultiplier;
InterfaceVolumeSlider.Value = _cfg.GetCVar(CCVars.InterfaceVolume) * 100f / ContentAudioSystem.InterfaceMultiplier;
AmbienceSoundsSlider.Value = _cfg.GetCVar(CCVars.MaxAmbientSources);
@@ -166,6 +172,8 @@ namespace Content.Client.Options.UI.Tabs
Math.Abs(AmbientMusicVolumeSlider.Value - _cfg.GetCVar(CCVars.AmbientMusicVolume) * 100f / ContentAudioSystem.AmbientMusicMultiplier) < 0.01f;
var isLobbyVolumeSame =
Math.Abs(LobbyVolumeSlider.Value - _cfg.GetCVar(CCVars.LobbyMusicVolume) * 100f / ContentAudioSystem.LobbyMultiplier) < 0.01f;
var isInterfaceVolumeSame =
Math.Abs(InterfaceVolumeSlider.Value - _cfg.GetCVar(CCVars.InterfaceVolume) * 100f / ContentAudioSystem.InterfaceMultiplier) < 0.01f;
var isAmbientSoundsSame = (int)AmbienceSoundsSlider.Value == _cfg.GetCVar(CCVars.MaxAmbientSources);
var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled);
@@ -173,7 +181,7 @@ namespace Content.Client.Options.UI.Tabs
var isEventSame = EventMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.EventMusicEnabled);
var isAdminSoundsSame = AdminSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.AdminSoundsEnabled);
var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientMusicVolumeSame && isAmbientSoundsSame && isLobbySame && isRestartSoundsSame && isEventSame
&& isAdminSoundsSame && isLobbyVolumeSame;
&& isAdminSoundsSame && isLobbyVolumeSame && isInterfaceVolumeSame;
ApplyButton.Disabled = isEverythingSame;
ResetButton.Disabled = isEverythingSame;
MasterVolumeLabel.Text =
@@ -186,6 +194,8 @@ namespace Content.Client.Options.UI.Tabs
Loc.GetString("ui-options-volume-percent", ("volume", AmbienceVolumeSlider.Value / 100));
LobbyVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", LobbyVolumeSlider.Value / 100));
InterfaceVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", InterfaceVolumeSlider.Value / 100));
AmbienceSoundsLabel.Text = ((int)AmbienceSoundsSlider.Value).ToString();
}
}

View File

@@ -285,7 +285,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
private void OnWindowOpened()
{
if (ActionButton != null)
ActionButton.Pressed = true;
ActionButton.SetClickPressed(true);
SearchAndDisplay();
}
@@ -293,7 +293,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
private void OnWindowClosed()
{
if (ActionButton != null)
ActionButton.Pressed = false;
ActionButton.SetClickPressed(false);
}
public void OnStateExited(GameplayState state)

View File

@@ -355,6 +355,7 @@ public sealed class ActionButton : Control, IEntityControl
{
base.MouseEntered();
UserInterfaceManager.HoverSound();
_beingHovered = true;
DrawModeChanged();
}

View File

@@ -127,14 +127,12 @@ public sealed class AdminUIController : UIController, IOnStateEntered<GameplaySt
private void OnWindowOpen()
{
if (AdminButton != null)
AdminButton.Pressed = true;
AdminButton?.SetClickPressed(true);
}
private void OnWindowClosed()
{
if (AdminButton != null)
AdminButton.Pressed = false;
AdminButton?.SetClickPressed(false);
}
private void OnWindowDisposed()

View File

@@ -121,6 +121,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
LobbyAHelpButton.Pressed = pressed;
}
UIManager.ClickSound();
UnreadAHelpRead();
}

View File

@@ -184,7 +184,7 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
if (CharacterButton != null)
{
CharacterButton.Pressed = !_window.IsOpen;
CharacterButton.SetClickPressed(!_window.IsOpen);
}
if (_window.IsOpen)

View File

@@ -51,8 +51,8 @@ public sealed class EscapeUIController : UIController, IOnStateEntered<GameplayS
EscapeButton.OnPressed += EscapeButtonOnOnPressed;
}
private void ActivateButton() => EscapeButton!.Pressed = true;
private void DeactivateButton() => EscapeButton!.Pressed = false;
private void ActivateButton() => EscapeButton!.SetClickPressed(true);
private void DeactivateButton() => EscapeButton!.SetClickPressed(false);
public void OnStateEntered(GameplayState state)
{

View File

@@ -139,12 +139,13 @@ public sealed class GuidebookUIController : UIController, IOnStateEntered<LobbyS
if (_guideWindow.IsOpen)
{
UIManager.ClickSound();
_guideWindow.Close();
return;
}
if (GuidebookButton != null)
GuidebookButton.Pressed = !_guideWindow.IsOpen;
GuidebookButton.SetClickPressed(!_guideWindow.IsOpen);
if (guides == null)
{

View File

@@ -243,7 +243,9 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
}
UpdateInventoryHotbar(_playerInventory);
_inventoryHotbar.Visible = !_inventoryHotbar.Visible;
var shouldBeVisible = !_inventoryHotbar.Visible;
_inventoryHotbar.Visible = shouldBeVisible;
}
// Neuron Activation

View File

@@ -172,10 +172,12 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
return;
if (_sandbox.SandboxAllowed && _window.IsOpen != true)
{
UIManager.ClickSound();
_window.OpenCentered();
}
else
{
UIManager.ClickSound();
_window.Close();
}
}

View File

@@ -81,6 +81,12 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<float> LobbyMusicVolume =
CVarDef.Create("ambience.lobby_music_volume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);
/// <summary>
/// UI volume.
/// </summary>
public static readonly CVarDef<float> InterfaceVolume =
CVarDef.Create("audio.interface_volume", 0.50f, CVar.ARCHIVE | CVar.CLIENTONLY);
/*
* Status
*/
@@ -573,6 +579,16 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<bool> DatabaseSynchronous =
CVarDef.Create("database.sync", false, CVar.SERVERONLY);
/*
* Interface
*/
public static readonly CVarDef<string> UIClickSound =
CVarDef.Create("interface.click_sound", "/Audio/UserInterface/click.ogg", CVar.REPLICATED);
public static readonly CVarDef<string> UIHoverSound =
CVarDef.Create("interface.hover_sound", "/Audio/UserInterface/hover.ogg", CVar.REPLICATED);
/*
* Outline
*/

View File

@@ -0,0 +1,11 @@
- files:
- click.ogg
license: "CC0-1.0"
copyright: "Made by el_boss, edited by mirrorcult"
source: "https://freesound.org/people/el_boss/sounds/677861/"
- files:
- hover.ogg
license: "CC0-1.0"
copyright: "Made by MATRIXXX_, edited by metalgearsloth"
source: "https://freesound.org/people/MATRIXXX_/sounds/703884/"

Binary file not shown.

Binary file not shown.

View File

@@ -27,6 +27,7 @@ ui-options-midi-volume = MIDI (Instrument) Volume:
ui-options-ambient-music-volume = Ambient music volume:
ui-options-ambience-volume = Ambience volume:
ui-options-lobby-volume = Lobby & Round-end volume:
ui-options-interface-volume = Interface volume:
ui-options-ambience-max-sounds = Ambience simultaneous sounds:
ui-options-lobby-music = Lobby & Round-end Music
ui-options-restart-sounds = Round Restart Sounds