1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 04:22: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] [Test]
public void TestOutOfOrderStartTimes() 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.Animations;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Screens.Play;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -115,6 +116,21 @@ namespace osu.Game.Storyboards.Drawables
Animation.ApplyTransforms(this); 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() private void skinSourceChanged()
{ {
ClearFrames(); ClearFrames();

View File

@ -54,6 +54,14 @@ namespace osu.Game.Storyboards
return firstAlpha.startTime; 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. // 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. // The sprite's StartTime will be determined by the earliest command, regardless of type.
double earliestStartTime = TimelineGroup.StartTime; double earliestStartTime = TimelineGroup.StartTime;