diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index 06fe22a95e..62c43a0851 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -220,6 +220,16 @@ namespace osu.Game.Rulesets.Objects.Drawables
OnNewResult?.Invoke(this, Result);
}
+ ///
+ /// Should be called at least once after lifetime of this hit object is end.
+ ///
+ public void OnLifetimeEnd()
+ {
+ foreach (var nested in NestedHitObjects)
+ nested.OnLifetimeEnd();
+ UpdateResult(false);
+ }
+
///
/// Processes this , checking if a scoring result has occurred.
///
diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs
index 00632b3d3e..2f3a384e95 100644
--- a/osu.Game/Rulesets/UI/HitObjectContainer.cs
+++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs
@@ -31,5 +31,11 @@ namespace osu.Game.Rulesets.UI
int i = yObj.HitObject.StartTime.CompareTo(xObj.HitObject.StartTime);
return i == 0 ? CompareReverseChildID(x, y) : i;
}
+
+ protected override void OnChildLifetimeBoundaryCrossed(LifetimeBoundaryCrossedEvent e)
+ {
+ if (e.Kind == LifetimeBoundaryKind.End && e.Direction == LifetimeBoundaryCrossingDirection.Forward && e.Child is DrawableHitObject hitObject)
+ hitObject.OnLifetimeEnd();
+ }
}
}