diff --git a/osu.Game/Storyboards/IStoryboardElement.cs b/osu.Game/Storyboards/IStoryboardElement.cs
index c4c150a8a4..377ad57ab2 100644
--- a/osu.Game/Storyboards/IStoryboardElement.cs
+++ b/osu.Game/Storyboards/IStoryboardElement.cs
@@ -14,4 +14,17 @@ namespace osu.Game.Storyboards
Drawable CreateDrawable();
}
+
+ public static class StoryboardElementExtensions
+ {
+ ///
+ /// Returns the end time of this object.
+ ///
+ ///
+ /// This returns the where available, falling back to otherwise.
+ ///
+ /// The object.
+ /// The end time of this object.
+ public static double GetEndTime(this IStoryboardElement storyboardElement) => (storyboardElement as IStoryboardElementHasDuration)?.EndTime ?? storyboardElement.StartTime;
+ }
}
diff --git a/osu.Game/Storyboards/IStoryboardElementHasDuration.cs b/osu.Game/Storyboards/IStoryboardElementHasDuration.cs
index e6ee373812..daa0c55704 100644
--- a/osu.Game/Storyboards/IStoryboardElementHasDuration.cs
+++ b/osu.Game/Storyboards/IStoryboardElementHasDuration.cs
@@ -3,6 +3,9 @@
namespace osu.Game.Storyboards
{
+ ///
+ /// A StoryboardElement that ends at a different time than its start time.
+ ///
public interface IStoryboardElementHasDuration
{
double EndTime { get; }
diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs
index 0b02a4921b..bc61f704dd 100644
--- a/osu.Game/Storyboards/Storyboard.cs
+++ b/osu.Game/Storyboards/Storyboard.cs
@@ -44,7 +44,7 @@ namespace osu.Game.Storyboards
/// This iterates all elements and as such should be used sparingly or stored locally.
/// Videos and samples return StartTime as their EndTIme.
///
- public double? LatestEventTime => Layers.SelectMany(l => l.Elements.OfType()).OrderByDescending(e => e.EndTime).FirstOrDefault()?.EndTime;
+ public double? LatestEventTime => Layers.SelectMany(l => l.Elements).OrderBy(e => e.GetEndTime()).LastOrDefault()?.GetEndTime();
///
/// Depth of the currently front-most storyboard layer, excluding the overlay layer.