Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixing animations using FlareControls stopping previous animations #139

Open
stx opened this issue Aug 25, 2019 · 9 comments
Open

Mixing animations using FlareControls stopping previous animations #139

stx opened this issue Aug 25, 2019 · 9 comments
Assignees

Comments

@stx
Copy link

stx commented Aug 25, 2019

Hi there! We have 2 animations: idle (loop) and speak. These animate different layers.

I would expect that we could use FlareControls().play('idle') initially, and then FlareControls().play('speak') each time we need to play it.

However, the moment "speak" is played, idle is stopped. This seems like odd behavior given the emphasis on mixing animations, or perhaps I'm doing something wrong.

If idle is moved to the FlareActor's animation property, this works as expected. Idle loops, speech plays as necessary.

However, the problem with this strategy comes when we introduce a third mix: idle, jump and speak.

With idle on loop on the FlareActor animation property, + play('jump') on demand + play('speak') on demand causes issues. The moment speak is played, jump is stopped.

Again, these animations are for different layers. This seems like a bug... what is the simplest way to be able to mix and fire animations in this way?

@neurowave
Copy link
Contributor

I'm not sure about the code part, I'll let someone else from our team address that, but on the animation side: can you share the Flare file? I can take a look and make sure there aren't any competing keys in your animations that might be causing this. One way to test this is to mix the animations in Flare by hitting the play button next to each animation (in the animations list).

@stx
Copy link
Author

stx commented Aug 26, 2019

@neurowave Can see it here: https://www.2dimensions.com/a/s-che/files/flare/selfy - idle-1 (enable looping) and speech-1.

On the Flare web side, idle-1 loop + speech-1 mixes perfect.

In Flare Flutter, .play('idle-1') -> .play('speech-1'), idle-1 will be stopped.

@luigi-rosso luigi-rosso self-assigned this Aug 27, 2019
@luigi-rosso
Copy link
Contributor

Hey @stx! FlareControls will play one-shot animations over each other and drop previous ones once the incoming animation is ramped up to 100% (1.0) mix. However, looping animations should always stay in the mix, so it's weird that idle-1 is getting stopped/dropped.

I'll try to set up an isolated test for this today to see if I can track down the bug.

In the meantime, you could use the lower level FlareController and get full control over the mixing by calling animation.apply in the correct order yourself. Here's a simple demo with our penguin example: https://github.com/2d-inc/Flare-Flutter/tree/stable/example/penguin_dance

Note you'd have to advance time for each animation manually too (so it gets tedious). We have plans for creating a visual state machine to control all these various animation play/mix states in the future. All directly from Flare!

@luigi-rosso
Copy link
Contributor

I can repro the problem. One hacky fix is to simply set "idle-1" as the animation on the FlareActor, this will play before any of the FlareControls animations and keep looping.

Still looking into why the FlareControls stop "idle-1".

@stx
Copy link
Author

stx commented Aug 27, 2019

@luigi-rosso Thanks for looking into this. Yes, I’ve been using that workaround. The problem is when I want to mix two on-demand plays on top of it. Idle keeps working, but the first play() is stopped when second play() is started.

@luigi-rosso
Copy link
Contributor

I see why it's happening. FlareControls currently removes all the animations that came prior to a fully mixed in one. That's a bug but it has been working that way for so long that I need to spend a little more time with it to figure out what the full impact of fixing that is.

In the meantime, if you want your own FlareControls with a fix, this is the delta:
image

Copy/pastable:

if (lastFullyMixed != -1) {
      int removeIndex = 0;
      for (int i = 0; i < lastFullyMixed; i++) {
        if (!_animationLayers[i].animation.isLooping) {
          _animationLayers.removeAt(removeIndex);
        } else {
          // Didn't remove it, nudge index forward
          removeIndex++;
        }
      }
    }

Full gist of the changed file (maybe rename to LoopingFlareControls/looping_flare_controls.dart or something to keep it separate from the main codebase for now):
https://gist.github.com/luigi-rosso/a700aabbad8ddc8f64417209889c1b01

@stx
Copy link
Author

stx commented Aug 27, 2019

@luigi-rosso That fix does keep the idle playing, but the much bigger issue is, because there is no workaround using FlareActor that I've found, even with one off animations without interfering layers, playing animation 1 and then 2 will simply stop animation 1 in place. Do you have a solution for that?

@luigi-rosso
Copy link
Contributor

You could completely delete the code that removes animations prior to the fully mixed one (the code just changed above). That’ll keep animations around until they complete. Sorry not at my desk to provide an example. I can do that later today.

@stx
Copy link
Author

stx commented Aug 27, 2019

Yup, that did it. Working perfectly and behaves exactly as I'd expect it now. Thanks a ton!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants