1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 00:02:54 +08:00

Merge pull request #20253 from peppy/fix-execute-me-storyboard

Fix `world.execute(me)` storyboard animation incorrectness
This commit is contained in:
Dan Balasescu 2022-09-12 15:02:14 +09:00 committed by GitHub
commit 1b63459d4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 0 deletions

View File

@ -97,6 +97,25 @@ namespace osu.Game.Tests.Beatmaps.Formats
}
}
[Test]
public void TestCorrectAnimationStartTime()
{
var decoder = new LegacyStoryboardDecoder();
using (var resStream = TestResources.OpenResource("animation-starts-before-alpha.osb"))
using (var stream = new LineBufferedReader(resStream))
{
var storyboard = decoder.Decode(stream);
StoryboardLayer background = storyboard.Layers.Single(l => l.Depth == 3);
Assert.AreEqual(1, background.Elements.Count);
Assert.AreEqual(2000, background.Elements[0].StartTime);
// This property should be used in DrawableStoryboardAnimation as a starting point for animation playback.
Assert.AreEqual(1000, (background.Elements[0] as StoryboardAnimation)?.EarliestTransformTime);
}
}
[Test]
public void TestOutOfOrderStartTimes()
{

View File

@ -0,0 +1,5 @@
[Events]
//Storyboard Layer 0 (Background)
Animation,Background,Centre,"img.jpg",320,240,2,150,LoopForever
S,0,1000,1500,0.08 // animation should start playing from this point in time..
F,0,2000,,0,1 // .. not this point in time

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Textures;
using osu.Framework.Utils;
using osu.Game.Screens.Play;
using osu.Game.Skinning;
using osuTK;
@ -115,6 +116,21 @@ namespace osu.Game.Storyboards.Drawables
Animation.ApplyTransforms(this);
}
[Resolved]
private IGameplayClock gameplayClock { get; set; }
protected override void LoadComplete()
{
base.LoadComplete();
// Framework animation class tries its best to synchronise the animation at LoadComplete,
// but in some cases (such as fast forward) this results in an incorrect start offset.
//
// In the case of storyboard animations, we want to synchronise with game time perfectly
// so let's get a correct time based on gameplay clock and earliest transform.
PlaybackPosition = gameplayClock.CurrentTime - Animation.EarliestTransformTime;
}
private void skinSourceChanged()
{
ClearFrames();

View File

@ -54,6 +54,14 @@ namespace osu.Game.Storyboards
return firstAlpha.startTime;
}
return EarliestTransformTime;
}
}
public double EarliestTransformTime
{
get
{
// If we got to this point, either no alpha commands were present, or the earliest had a non-zero start value.
// The sprite's StartTime will be determined by the earliest command, regardless of type.
double earliestStartTime = TimelineGroup.StartTime;