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:
98
Content.Client/Audio/AudioUIController.cs
Normal file
98
Content.Client/Audio/AudioUIController.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -355,6 +355,7 @@ public sealed class ActionButton : Control, IEntityControl
|
||||
{
|
||||
base.MouseEntered();
|
||||
|
||||
UserInterfaceManager.HoverSound();
|
||||
_beingHovered = true;
|
||||
DrawModeChanged();
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -121,6 +121,7 @@ public sealed class AHelpUIController: UIController, IOnSystemChanged<BwoinkSyst
|
||||
LobbyAHelpButton.Pressed = pressed;
|
||||
}
|
||||
|
||||
UIManager.ClickSound();
|
||||
UnreadAHelpRead();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
11
Resources/Audio/UserInterface/attributions.yml
Normal file
11
Resources/Audio/UserInterface/attributions.yml
Normal 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/"
|
||||
BIN
Resources/Audio/UserInterface/click.ogg
Normal file
BIN
Resources/Audio/UserInterface/click.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/UserInterface/hover.ogg
Normal file
BIN
Resources/Audio/UserInterface/hover.ogg
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user