diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs
index 00734810b3..51deae6e85 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs
@@ -71,11 +71,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
switch (state)
{
case ArmedState.Miss:
- this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out).Expire();
+ this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out);
break;
case ArmedState.Hit:
- this.FadeOut().Expire();
+ this.FadeOut();
break;
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
index e5b114ca81..5bfa07bd14 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
@@ -51,11 +51,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
switch (state)
{
case ArmedState.Miss:
- this.FadeOut(150, Easing.In).Expire();
+ this.FadeOut(150, Easing.In);
break;
case ArmedState.Hit:
- this.FadeOut(150, Easing.OutQuint).Expire();
+ this.FadeOut(150, Easing.OutQuint);
break;
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
index 985dcbca86..85fd68efdd 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
@@ -86,6 +86,26 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AccentColour.BindValueChanged(accent => ApproachCircle.Colour = accent.NewValue, true);
}
+ public override double LifetimeStart
+ {
+ get => base.LifetimeStart;
+ set
+ {
+ base.LifetimeStart = value;
+ ApproachCircle.LifetimeStart = value;
+ }
+ }
+
+ public override double LifetimeEnd
+ {
+ get => base.LifetimeEnd;
+ set
+ {
+ base.LifetimeEnd = value;
+ ApproachCircle.LifetimeEnd = value;
+ }
+ }
+
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
Debug.Assert(HitObject.HitWindows != null);
@@ -132,22 +152,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Expire(true);
hitArea.HitAction = null;
-
- // override lifetime end as FadeIn may have been changed externally, causing out expiration to be too early.
- LifetimeEnd = HitObject.StartTime + HitObject.HitWindows.WindowFor(HitResult.Miss);
break;
case ArmedState.Miss:
ApproachCircle.FadeOut(50);
this.FadeOut(100);
- Expire();
break;
case ArmedState.Hit:
ApproachCircle.FadeOut(50);
// todo: temporary / arbitrary
- this.Delay(800).Expire();
+ this.Delay(800).FadeOut();
break;
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index fcd42314fc..8a7e5117f9 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -41,6 +41,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ // Manually set to reduce the number of future alive objects to a bare minimum.
+ LifetimeStart = HitObject.StartTime - HitObject.TimePreempt;
+ }
+
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement);
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index 00c953c393..65f1d5e15f 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -219,10 +219,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
break;
}
- this.FadeOut(fade_out_time, Easing.OutQuint).Expire();
+ this.FadeOut(fade_out_time, Easing.OutQuint);
}
-
- Expire(true);
}
public Drawable ProxiedLayer => HeadCircle.ApproachCircle;
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
index 49aaa2aaea..b1185ddba8 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
@@ -219,10 +219,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
switch (state)
{
- case ArmedState.Idle:
- Expire(true);
- break;
-
case ArmedState.Hit:
sequence.ScaleTo(Scale * 1.2f, 320, Easing.Out);
break;
@@ -231,8 +227,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
sequence.ScaleTo(Scale * 0.8f, 320, Easing.In);
break;
}
-
- Expire();
}
}
}
diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
index ea7eee8bb8..df12ebc514 100644
--- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
@@ -70,13 +70,7 @@ namespace osu.Game.Rulesets.Osu.UI
base.Add(h);
}
- private void addApproachCircleProxy(Drawable d)
- {
- var proxy = d.CreateProxy();
- proxy.LifetimeStart = d.LifetimeStart;
- proxy.LifetimeEnd = d.LifetimeEnd;
- approachCircles.Add(proxy);
- }
+ private void addApproachCircleProxy(Drawable d) => approachCircles.Add(d.CreateProxy());
public override void PostProcess()
{
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
index f4407a7b54..8e16a21199 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
@@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
case ArmedState.Hit:
case ArmedState.Miss:
- this.Delay(HitObject.Duration).FadeOut(100).Expire();
+ this.Delay(HitObject.Duration).FadeOut(100);
break;
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
index cef9a53deb..25b6141a0e 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
@@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
switch (state)
{
case ArmedState.Hit:
- this.ScaleTo(0, 100, Easing.OutQuint).Expire();
+ this.ScaleTo(0, 100, Easing.OutQuint);
break;
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
index 676ecd5a0b..4b25ff0ecc 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
@@ -105,12 +105,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
validActionPressed = false;
UnproxyContent();
- this.Delay(HitObject.HitWindows.WindowFor(HitResult.Miss)).Expire();
break;
case ArmedState.Miss:
- this.FadeOut(100)
- .Expire();
+ this.FadeOut(100);
break;
case ArmedState.Hit:
@@ -129,9 +127,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
.Then()
.MoveToY(gravity_travel_height * 2, gravity_time * 2, Easing.In);
- this.FadeOut(800)
- .Expire();
-
+ this.FadeOut(800);
break;
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
index 094ad1230f..07af7fe7e0 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -208,8 +208,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
this.FadeOut(transition_duration, Easing.Out);
bodyContainer.ScaleTo(1.4f, transition_duration);
-
- Expire();
}
break;
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index e3390c8cf0..90c49a0144 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -153,7 +153,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (UseTransformStateManagement)
{
- lifetimeStart = null;
LifetimeEnd = double.MaxValue;
double transformTime = HitObject.StartTime - InitialLifetimeOffset;
@@ -173,6 +172,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
state.Value = newState;
}
}
+
+ if (state.Value != ArmedState.Idle && LifetimeEnd == double.MaxValue)
+ Expire();
}
else
state.Value = newState;
@@ -203,6 +205,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
///
/// Apply transforms based on the current . Previous states are automatically cleared.
+ /// In the case of a non-idle , and if was not set during this call, will be invoked.
///
/// The new armed state.
protected virtual void UpdateStateTransforms(ArmedState state)