mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 15:07:44 +08:00
Fix spinner ticks not playing samples correctly sometimes
Noticed this during work on https://github.com/ppy/osu/pull/25185. In some circumstances, it seemed that spinner bonus ticks (and mostly them specifically) would not always play with the correct volume. Hours of debugging later pointed at a trace at `DrawableAudioWrapper.refreshLayoutFromParent()` not firing sometimes. Initially I thought it to be some sort of framework bug, but after preparing a diff and running final checks, I noticed that sometimes the sample was being played *by a `PoolableSkinnableSample` that wasn't loaded*. And determining why *that* is the case turned out with this diff. As it happens, spinner ticks get assigned a start time proportionally, i.e. the 1st of 10 ticks is placed at 10% of the duration, the 2nd at 20%, and so on. The start time generally shouldn't matter, because the spinner is manually judging the ticks. *However*, the ticks *still* receive a lifetime start / end in the same way normal objects do, which means that in some cases they can *not be alive* when they're hit, which means that the `DrawableAudioWrapper` flow *hasn't had a chance to run*, and rightly so. To fix, ensure that all spinner ticks are alive throughout the entirety of the spinner's duration.
This commit is contained in:
parent
fc1254ba47
commit
cfd8d05fde
@ -4,6 +4,8 @@
|
||||
#nullable disable
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
@ -25,6 +27,26 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
Origin = Anchor.Centre;
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
{
|
||||
base.OnApply();
|
||||
|
||||
// the tick can be theoretically judged at any point in the spinner's duration,
|
||||
// so it must be alive throughout the spinner's entire lifetime.
|
||||
// this mostly matters for correct sample playback.
|
||||
LifetimeStart = DrawableSpinner.HitObject.StartTime;
|
||||
}
|
||||
|
||||
protected override void UpdateHitStateTransforms(ArmedState state)
|
||||
{
|
||||
base.UpdateHitStateTransforms(state);
|
||||
|
||||
// the tick can be theoretically judged at any point in the spinner's duration,
|
||||
// so it must be alive throughout the spinner's entire lifetime (or until hit, whichever applies).
|
||||
// this mostly matters for correct sample playback.
|
||||
LifetimeEnd = (Result?.IsHit == true ? Result.TimeAbsolute : DrawableSpinner.HitObject.GetEndTime()) + (Samples?.Length ?? 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply a judgement result.
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user