1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 06:57:39 +08:00

Fix hit error meters not updating visual state when hidden

It is an expectation of users that when the HUD is shown after a period
of being hidden, it will visually reflect the state based on recent
judgements.

To achieve this, I've added `AlwaysPresent` and moved the transform
application to the meter level, rather than at a child level. If this is
seen as a bad direction, `AlwaysPresent` can be applied to the drawable
children and the transforms can be moved back.

Also of note, `ColourHitErrorMeter` is pretty weird. The flow class
could potentially be removed and reduce `AlwaysPresent` usage by one.
Can do that refactor as part of this PR if preferred.

Closes #18624.
This commit is contained in:
Dean Herbert 2022-06-13 16:37:26 +09:00
parent 17eaf7bb5c
commit 86163d2225
3 changed files with 33 additions and 38 deletions

View File

@ -400,6 +400,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{
const int arrow_move_duration = 800;
const int judgement_fade_in_duration = 100;
const int judgement_fade_out_duration = 5000;
if (!judgement.IsHit || judgement.HitObject.HitWindows?.WindowFor(HitResult.Miss) == 0)
return;
@ -420,12 +423,26 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
}
}
judgementsContainer.Add(new JudgementLine
var judgementLine = new JudgementLine
{
JudgementLineThickness = { BindTarget = JudgementLineThickness },
Y = getRelativeJudgementPosition(judgement.TimeOffset),
Colour = GetColourForHitResult(judgement.Type),
});
Alpha = 0,
Width = 0,
};
judgementsContainer.Add(judgementLine);
// Importantly, transforms should be applied in this method rather than constructed drawables
// to ensure that they are applied even when the `HitErrorMeter` is hidden (see `AlwaysPresent` usage).
judgementLine
.FadeTo(0.6f, judgement_fade_in_duration, Easing.OutQuint)
.ResizeWidthTo(1, judgement_fade_in_duration, Easing.OutQuint)
.Then()
.FadeOut(judgement_fade_out_duration)
.ResizeWidthTo(0, judgement_fade_out_duration, Easing.InQuint)
.Expire();
arrow.MoveToY(
getRelativeJudgementPosition(floatingAverage = floatingAverage * 0.9 + judgement.TimeOffset * 0.1)
@ -456,23 +473,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
protected override void LoadComplete()
{
const int judgement_fade_in_duration = 100;
const int judgement_fade_out_duration = 5000;
base.LoadComplete();
Alpha = 0;
Width = 0;
JudgementLineThickness.BindValueChanged(thickness => Height = thickness.NewValue, true);
this
.FadeTo(0.6f, judgement_fade_in_duration, Easing.OutQuint)
.ResizeWidthTo(1, judgement_fade_in_duration, Easing.OutQuint)
.Then()
.FadeOut(judgement_fade_out_duration)
.ResizeWidthTo(0, judgement_fade_out_duration, Easing.InQuint)
.Expire();
}
}

View File

@ -51,47 +51,37 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
Direction = FillDirection.Vertical;
LayoutDuration = animation_duration;
LayoutEasing = Easing.OutQuint;
AlwaysPresent = true;
}
public void Push(Color4 colour)
{
Add(new HitErrorCircle(colour, drawable_judgement_size));
var hitErrorCircle = new HitErrorCircle(colour);
Add(hitErrorCircle);
hitErrorCircle.FadeInFromZero(animation_duration, Easing.OutQuint);
hitErrorCircle.MoveToY(-drawable_judgement_size);
hitErrorCircle.MoveToY(0, animation_duration, Easing.OutQuint);
if (Children.Count > MAX_DISPLAYED_JUDGEMENTS)
Children.FirstOrDefault(c => !c.IsRemoved)?.Remove();
}
}
internal class HitErrorCircle : Container
internal class HitErrorCircle : Circle
{
public bool IsRemoved { get; private set; }
private readonly Circle circle;
public HitErrorCircle(Color4 colour, int size)
public HitErrorCircle(Color4 colour)
{
Size = new Vector2(size);
Child = circle = new Circle
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Colour = colour
};
}
protected override void LoadComplete()
{
base.LoadComplete();
circle.FadeInFromZero(animation_duration, Easing.OutQuint);
circle.MoveToY(-DrawSize.Y);
circle.MoveToY(0, animation_duration, Easing.OutQuint);
Colour = colour;
Size = new Vector2(drawable_judgement_size);
}
public void Remove()
{
IsRemoved = true;
this.FadeOut(animation_duration, Easing.OutQuint).Expire();
}
}

View File

@ -37,6 +37,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{
base.LoadComplete();
AlwaysPresent = true;
if (gameplayClockContainer != null)
gameplayClockContainer.OnSeek += Clear;