SpriterDotNet icon indicating copy to clipboard operation
SpriterDotNet copied to clipboard

Transitions do not play the full animation

Open KamiGrave opened this issue 5 years ago • 15 comments

I've got an idle animation that lasts for 1000 milliseconds and an attack animation that lasts for 600. On a transition with 100 milliseconds of transition time, only the very end of the attack animation plays. This depends on what progress the idle animation is on. If I transition at the start of the animation (near time 0) I see more of the animation. If I wait until the animation is half way through, I only get a 'thrust' as the transition tries to align the animations.

See the attached gif for what's happening inside the example application.

examplebroken

The first shows almost the full swing (what I'd consider to be a near successful transition), the second is the same animation but transitioned half way through the idle animation, and results in a thrust motion (which would be great if it was a thrust attack!). There's only two animations in the file, the idle and the attack. I removed the others to make it easier to debug. I can provide this file if required.

KamiGrave avatar Oct 03 '18 19:10 KamiGrave

Could you please provide Spriter project and code snippet you use to make a transition to be able to reproduce the issue?

rfadeev avatar Oct 09 '18 14:10 rfadeev

WeeKnights.zip

The code is just the MonoGame example from this repository. I had to edit the Constants file to add the scml file. I also edited the transition time in the ExampleGame.cs to be 100, instead of 1000. (line 103)

KamiGrave avatar Oct 09 '18 18:10 KamiGrave

This is the intended behaviour. What happens is, animations get interpolated based on a normalised progress. In this example:

Animation A is at 700/1000 ms or 0.7 progress You transition to B with a 100ms interval. Animation B starts at 0.7 progress or 600 * 0.7 == 420ms.

Usually, the transitions happen between animations such as walking/running/jumping and this behaviour makes them look more natural. On the other hand, attack animations are usually jumped into straight away i.e. no interpolation.

That being said, this use case is completely valid and I believe the right solution is to expand the interpolation methods with an enum to specify the interpolation mode. Something like: InterpolationMode.CurrentProgress InterpolationMode.FromStart

loodakrawa avatar Oct 09 '18 22:10 loodakrawa

I did a custom solution which basically involved me passing through the transition time and using that for getting the second animation frames. It's a bit of a hack for the moment to get things working (No idea what would happen if the transition time was longer than the target animation, I guess it would just hang at the last frame or loop). I am using the transitions to smooth out the move from one attack to another in a combo system, the attacks are data driven so creating bespoke animations isn't really an option. The hack I've done to the transition logic appears to be working for me, but it's not a very clean solution as you basically lose the ability to interpolate using the normalised progress as before.

KamiGrave avatar Oct 10 '18 07:10 KamiGrave

I'm running into this issue, and I can't seem to come up with a good way of transitioning to attack animations. I tried KamiGrave's solution but it doesn't really fix the problem completely for me. I'd be happy to give up the normalized transitions entirely if I could get it to cleanly transition to the start of animations. The way things are set up now transitions are basically useless for anything like an attack.

alextilkin avatar Jan 04 '20 10:01 alextilkin

@luciddream00 The solution I came up with was a bit of a hack and is in my own fork of the SpriterDotNet repo. There's probably a much cleaner solution that I didn't look for under the expectation that this may be fixed at some point in the main repo (this one) and I didn't want to clash with it. In retrospect, I should probably have introduced a clean solution and set it up for a pull request. As it happens, I'm no longer using SpriterDotNet or MonoGame, but this was one issue I resolved before moving onto an engine. It should be noted as well that I had to modify the animations as well because of the transition time from one attack to the other. There was also issues about events firing during the transitions that made things a bit difficult too.

KamiGrave avatar Jan 04 '20 19:01 KamiGrave

Thanks for the info. I think I came up with a pretty clean solution that loses the normalized transitions, but just uses simple transitions that work more like you'd expect for attacks and whatnot. If anyone else runs into this in the future, here is what I did:

At line 192 in the Animator class, I changed

if (NextAnimation != null && totalTransitionTime != 0.0f)
{
	elapsed += elapsed * factor * CurrentAnimation.Length / NextAnimation.Length;
	transitionTime += Math.Abs(elapsed);
	factor = transitionTime / totalTransitionTime;
	if (transitionTime >= totalTransitionTime)
	{
		float progress = Progress;
		Play(NextAnimation.Name);
		Progress = progress;
		NextAnimation = null;
	}
}

Time += elapsed;

to

if (NextAnimation != null && totalTransitionTime != 0.0f)
{
	elapsed += elapsed * factor * CurrentAnimation.Length / NextAnimation.Length;

	transitionTime += Math.Abs(elapsed);
	factor = transitionTime / totalTransitionTime;
	if (transitionTime >= totalTransitionTime)
	{
		//float progress = Progress;
		Play(NextAnimation.Name);
		Progress = 0;// progress;
		NextAnimation = null;
	}
}
else
{
	Time += elapsed;
}

and in FrameDataCalculator at line 34 I changed

float targetTimeSecond = targetTime / first.Length * second.Length;

to

float targetTimeSecond = 0;

Basically, all it does is have animations transition from the current animation to the start of the next animation.

alextilkin avatar Jan 04 '20 20:01 alextilkin

@luciddream00 Thanks, this absolutely solved transition issues. This should really be the default behavior, I dunno why the author thinks janky transitions are better.

Martenfur avatar Jul 11 '20 12:07 Martenfur

@luciddream00 Thanks, this absolutely solved transition issues. This should really be the default behavior, I dunno why the author thinks janky transitions are better.

I did it so people like you, who have nothing better to do than criticizing open source projects instead of actually contributing, have something to do.

loodakrawa avatar Jul 11 '20 14:07 loodakrawa

I did it so people like you, who have nothing better to do than criticizing open source projects instead of actually contributing, have something to do.

I mean. I could make my fork public and submit my changes, if you wanna. But you probably won't like them and won't merge them anyway, since you got pull requests open for two years.

Martenfur avatar Jul 11 '20 14:07 Martenfur

I did it so people like you, who have nothing better to do than criticizing open source projects instead of actually contributing, have something to do.

I mean. I could make my fork public and submit my changes, if you wanna. But you probably won't like them and won't merge them anyway, since you got pull requests open for two years.

You are probably right. Based on the lack of understanding you showed when you opened other issues in the past few days I highly doubt your code would improve this project in any way.

loodakrawa avatar Jul 15 '20 12:07 loodakrawa

For what it's worth, I very much appreciate the library even if I had to fiddle with it a bit to act the way I want.

alextilkin avatar Jul 15 '20 14:07 alextilkin

For what it's worth, I very much appreciate the library even if I had to fiddle with it a bit to act the way I want.

I'm very glad to hear that. That was my main motivation to go open source in the first place - hopefully help someone with the code I planned to write for myself anyway. I am trying to maintain it and improve it, but sometimes it's difficult to give it all the love it deserves due to, well, life happening. Since I'm already working on version 2 (albeit slowly) which is almost a complete rewrite, I'm less active in improving the current version since I'll address all these things (like this issue) directly in the next version.

loodakrawa avatar Jul 15 '20 15:07 loodakrawa

You are probably right. Based on the lack of understanding you showed when you opened other issues in the past few days I highly doubt your code would improve this project in any way.

Your tendency to overengineer and my degree of understanding don't have much in common, tbh. And damn, why so salty? I am genuinely trying to help your thingy and you're behaving like a total dick.

Martenfur avatar Jul 15 '20 23:07 Martenfur

You are probably right. Based on the lack of understanding you showed when you opened other issues in the past few days I highly doubt your code would improve this project in any way.

Your tendency to overengineer and my degree of understanding don't have much in common, tbh. And damn, why so salty? I am genuinely trying to help your thingy and you're behaving like a total dick.

You've been nothing but rude and condescending and you haven't suggested a single useful thing. If this is your way of "trying to help", go do it somewhere else.

loodakrawa avatar Jul 16 '20 08:07 loodakrawa