1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 19:54:15 +08:00

Fix pause ambience loop not playing at fail screen (#37663)

Matches stable.

---

Addresses https://github.com/ppy/osu/discussions/37580.
This commit is contained in:
Dean Herbert
2026-05-07 17:51:19 +09:00
committed by GitHub
Unverified
parent 7f385c7873
commit 1818c1b1e6
3 changed files with 61 additions and 62 deletions
+60 -2
View File
@@ -5,6 +5,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -13,6 +15,8 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@@ -23,6 +27,7 @@ using osuTK;
using osuTK.Graphics;
using osu.Game.Localisation;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Skinning;
using osu.Game.Utils;
namespace osu.Game.Screens.Play
@@ -76,10 +81,15 @@ namespace osu.Game.Screens.Play
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, GameHost? host)
{
Children = new Drawable[]
{
pauseLoop = new SkinnableSound(new SampleInfo("Gameplay/pause-loop"))
{
Looping = true,
Volume = { Value = 0 }
},
new Box
{
RelativeSizeAxes = Axes.Both,
@@ -142,6 +152,9 @@ namespace osu.Game.Screens.Play
State.ValueChanged += _ => InternalButtons.Deselect();
updateInfoText();
if (host != null)
windowActive.BindTo(host.IsActive);
}
private int retries;
@@ -164,9 +177,15 @@ namespace osu.Game.Screens.Play
{
this.FadeIn(TRANSITION_DURATION, Easing.In);
updateInfoText();
startPauseLoop();
}
protected override void PopOut() => this.FadeOut(TRANSITION_DURATION, Easing.In);
protected override void PopOut()
{
this.FadeOut(TRANSITION_DURATION, Easing.In);
stopPauseLoop();
}
protected void AddButton(LocalisableString text, Color4 colour, Action? action)
{
@@ -283,5 +302,44 @@ namespace osu.Game.Screens.Play
return base.Handle(e);
}
#region Pause loop sound handling
public override bool IsPresent => base.IsPresent || pauseLoop.IsPlaying;
private SkinnableSound pauseLoop = null!;
private readonly IBindable<bool> windowActive = new Bindable<bool>(true);
private float targetVolume => windowActive.Value && State.Value == Visibility.Visible ? 1.0f : 0;
protected override void LoadComplete()
{
base.LoadComplete();
// Schedule required because host.IsActive doesn't seem to always run on the update thread.
windowActive.BindValueChanged(_ => Schedule(() => pauseLoop.VolumeTo(targetVolume, 1000, Easing.Out)));
}
public void StopAllSamples()
{
if (!IsLoaded)
return;
pauseLoop.Stop();
}
private void startPauseLoop()
{
pauseLoop.VolumeTo(targetVolume, TRANSITION_DURATION, Easing.InQuint);
pauseLoop.Play();
}
private void stopPauseLoop()
{
pauseLoop.VolumeTo(targetVolume, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop());
}
#endregion
}
}
-60
View File
@@ -3,29 +3,17 @@
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Game.Audio;
using osu.Game.Input.Bindings;
using osu.Game.Localisation;
using osu.Game.Skinning;
namespace osu.Game.Screens.Play
{
public partial class PauseOverlay : GameplayMenuOverlay
{
public override bool IsPresent => base.IsPresent || pauseLoop.IsPlaying;
public override LocalisableString Header => GameplayMenuOverlayStrings.PausedHeader;
private SkinnableSound pauseLoop = null!;
protected override Action BackAction => () =>
{
if (Buttons.Any())
@@ -34,54 +22,6 @@ namespace osu.Game.Screens.Play
OnResume?.Invoke();
};
private readonly IBindable<bool> windowActive = new Bindable<bool>(true);
private float targetVolume => windowActive.Value && State.Value == Visibility.Visible ? 1.0f : 0;
[BackgroundDependencyLoader]
private void load(GameHost? host)
{
AddInternal(pauseLoop = new SkinnableSound(new SampleInfo("Gameplay/pause-loop"))
{
Looping = true,
Volume = { Value = 0 }
});
if (host != null)
windowActive.BindTo(host.IsActive);
}
protected override void LoadComplete()
{
base.LoadComplete();
// Schedule required because host.IsActive doesn't seem to always run on the update thread.
windowActive.BindValueChanged(_ => Schedule(() => pauseLoop.VolumeTo(targetVolume, 1000, Easing.Out)));
}
public void StopAllSamples()
{
if (!IsLoaded)
return;
pauseLoop.Stop();
}
protected override void PopIn()
{
base.PopIn();
pauseLoop.VolumeTo(targetVolume, TRANSITION_DURATION, Easing.InQuint);
pauseLoop.Play();
}
protected override void PopOut()
{
base.PopOut();
pauseLoop.VolumeTo(targetVolume, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop());
}
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
switch (e.Action)
+1
View File
@@ -1194,6 +1194,7 @@ namespace osu.Game.Screens.Play
// Eagerly clean these up as disposal of child components is asynchronous and may leave sounds playing beyond user expectations.
failAnimationContainer?.Stop();
PauseOverlay?.StopAllSamples();
FailOverlay?.StopAllSamples();
if (LoadedBeatmapSuccessfully && !GameplayState.HasPassed)
{