Remove the ability to ignore global volume (#11092)

# Objective

The ability to ignore the global volume doesn't seem desirable and
complicates the API.

#7706 added global volume and the ability to ignore it, but there was no
further discussion about whether that's useful. Feel free to discuss
here :)

## Solution

Replace the `Volume` type's functionality with the `VolumeLevel`. Remove
`VolumeLevel`.

I also removed `DerefMut` derive that effectively made the volume `pub`
and actually ensured that the volume isn't set below `0` even in release
builds.

## Migration Guide

The option to ignore the global volume using `Volume::Absolute` has been
removed and `Volume` now stores the volume level directly, removing the
need for the `VolumeLevel` struct.
This commit is contained in:
irate 2024-01-15 16:31:54 +01:00 committed by GitHub
parent 8c6d9b8103
commit c29a9729a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 61 deletions

View file

@ -1,51 +1,25 @@
use crate::{AudioSource, Decodable};
use bevy_asset::{Asset, Handle};
use bevy_derive::{Deref, DerefMut};
use bevy_derive::Deref;
use bevy_ecs::prelude::*;
use bevy_math::Vec3;
use bevy_reflect::prelude::*;
/// Defines the volume to play an audio source at.
#[derive(Clone, Copy, Debug, Reflect)]
pub enum Volume {
/// A volume level relative to the global volume.
Relative(VolumeLevel),
/// A volume level that ignores the global volume.
Absolute(VolumeLevel),
}
/// A volume level equivalent to a non-negative float.
#[derive(Clone, Copy, Deref, Debug, Reflect)]
pub struct Volume(pub(crate) f32);
impl Default for Volume {
fn default() -> Self {
Self::Relative(VolumeLevel::default())
}
}
impl Volume {
/// Create a new volume level relative to the global volume.
pub fn new_relative(volume: f32) -> Self {
Self::Relative(VolumeLevel::new(volume))
}
/// Create a new volume level that ignores the global volume.
pub fn new_absolute(volume: f32) -> Self {
Self::Absolute(VolumeLevel::new(volume))
}
}
/// A volume level equivalent to a non-negative float.
#[derive(Clone, Copy, Deref, DerefMut, Debug, Reflect)]
pub struct VolumeLevel(pub(crate) f32);
impl Default for VolumeLevel {
fn default() -> Self {
Self(1.0)
}
}
impl VolumeLevel {
impl Volume {
/// Create a new volume level.
pub fn new(volume: f32) -> Self {
debug_assert!(volume >= 0.0);
Self(volume)
Self(f32::max(volume, 0.))
}
/// Get the value of the volume level.
pub fn get(&self) -> f32 {
@ -53,7 +27,7 @@ impl VolumeLevel {
}
/// Zero (silent) volume level
pub const ZERO: Self = VolumeLevel(0.0);
pub const ZERO: Self = Volume(0.0);
}
/// The way Bevy manages the sound playback.
@ -106,7 +80,7 @@ impl PlaybackSettings {
/// Will play the associated audio source once.
pub const ONCE: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Once,
volume: Volume::Relative(VolumeLevel(1.0)),
volume: Volume(1.0),
speed: 1.0,
paused: false,
spatial: false,
@ -115,28 +89,19 @@ impl PlaybackSettings {
/// Will play the associated audio source in a loop.
pub const LOOP: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Loop,
volume: Volume::Relative(VolumeLevel(1.0)),
speed: 1.0,
paused: false,
spatial: false,
..PlaybackSettings::ONCE
};
/// Will play the associated audio source once and despawn the entity afterwards.
pub const DESPAWN: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Despawn,
volume: Volume::Relative(VolumeLevel(1.0)),
speed: 1.0,
paused: false,
spatial: false,
..PlaybackSettings::ONCE
};
/// Will play the associated audio source once and remove the audio components afterwards.
pub const REMOVE: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Remove,
volume: Volume::Relative(VolumeLevel(1.0)),
speed: 1.0,
paused: false,
spatial: false,
..PlaybackSettings::ONCE
};
/// Helper to start in a paused state.
@ -196,21 +161,21 @@ impl SpatialListener {
}
}
/// Use this [`Resource`] to control the global volume of all audio with a [`Volume::Relative`] volume.
/// Use this [`Resource`] to control the global volume of all audio.
///
/// Note: changing this value will not affect already playing audio.
#[derive(Resource, Default, Clone, Copy, Reflect)]
#[reflect(Resource)]
pub struct GlobalVolume {
/// The global volume of all audio.
pub volume: VolumeLevel,
pub volume: Volume,
}
impl GlobalVolume {
/// Create a new [`GlobalVolume`] with the given volume.
pub fn new(volume: f32) -> Self {
Self {
volume: VolumeLevel::new(volume),
volume: Volume::new(volume),
}
}
}

View file

@ -1,6 +1,6 @@
use crate::{
AudioSourceBundle, Decodable, GlobalVolume, PlaybackMode, PlaybackSettings, SpatialAudioSink,
SpatialListener, SpatialScale, Volume,
SpatialListener, SpatialScale,
};
use bevy_asset::{Asset, Assets, Handle};
use bevy_ecs::{prelude::*, system::SystemParam};
@ -159,10 +159,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
};
sink.set_speed(settings.speed);
match settings.volume {
Volume::Relative(vol) => sink.set_volume(vol.0 * global_volume.volume.0),
Volume::Absolute(vol) => sink.set_volume(vol.0),
}
sink.set_volume(settings.volume.0 * global_volume.volume.0);
if settings.paused {
sink.pause();
@ -202,10 +199,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
};
sink.set_speed(settings.speed);
match settings.volume {
Volume::Relative(vol) => sink.set_volume(vol.0 * global_volume.volume.0),
Volume::Absolute(vol) => sink.set_volume(vol.0),
}
sink.set_volume(settings.volume.0 * global_volume.volume.0);
if settings.paused {
sink.pause();

View file

@ -63,7 +63,7 @@ struct AudioPlaySet;
/// Insert an [`AudioBundle`] onto your entities to play audio.
#[derive(Default)]
pub struct AudioPlugin {
/// The global volume for all audio entities with a [`Volume::Relative`] volume.
/// The global volume for all audio entities.
pub global_volume: GlobalVolume,
/// The scale factor applied to the positions of audio sources and listeners for
/// spatial audio.
@ -72,12 +72,11 @@ pub struct AudioPlugin {
impl Plugin for AudioPlugin {
fn build(&self, app: &mut App) {
app.register_type::<VolumeLevel>()
app.register_type::<Volume>()
.register_type::<GlobalVolume>()
.register_type::<SpatialListener>()
.register_type::<SpatialScale>()
.register_type::<PlaybackMode>()
.register_type::<Volume>()
.register_type::<PlaybackSettings>()
.insert_resource(self.global_volume)
.insert_resource(self.spatial_scale)