Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Animancer - No more Animator Controllers, just get an AnimationClip and play it

Discussion in 'Assets and Asset Store' started by Kybernetik, Oct 8, 2018.

  1. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    title.png
    [Pro] [Lite] [Documentation] [Examples] [Forum] [AnimancerUnityPlugin@gmail.com]

    Animancer
    is a powerful animation system which provides more control over your animations and solves many of the common problems with Animator Controllers by allowing scripts to directly reference AnimationClips and play them without any additional setup steps.

    It also supports a hybrid approach utilising both Animator Controllers and direct references for different tasks. Or you can even mix multiple Animator Controllers on a single character. You get total freedom to structure each project to suit your needs.

    Animancer Lite allows you to try out all the features for FREE while Animancer Pro removes any restrictions and includes the full source code.

    It has detailed documentation, lots of examples, great performance, and high compatability with other systems.
     
    Last edited: Aug 13, 2019
  2. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,174
    This plugin looks very interesting!

    I'm quite surprised that it didn't got the attention it deserves in this forum.

    I have come to a point where I hate the Animator fsm graphs and want to revert all to code.

    I will buy this plugin just to get rid of the Animator graph madness,

    Good job!
     
  3. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Thanks for the interest. The Lite version lets you try out all the features in the Unity Editor so you might as well try it before buying, but from what you've said I expect my plugin will be exactly what you've been looking for.
     
    elias_t likes this.
  4. ikemen_blueD

    ikemen_blueD

    Joined:
    Jan 19, 2013
    Posts:
    312
    I purchased it long ago. Now, I just try it today. It totally blows my mind. Everything is so easy. You have 100% control of what you want to play, when you want to play? No more messy Mecanim states and conditions wow even though I can do some tricks to make Mecanim behaves like a Legacy way, but still this is gold. Any plans for future update?
     
    elias_t likes this.
  5. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    I'm glad you like it. I'm currently working on v3.0. It doesn't have any major new features, but lots of little improvements all over. Much better examples, some performance improvements, and various other small changes and bug fixes throughout the system. I hope to get it finished in the next month or two.
     
    JoeStrout, ikemen_blueD and elias_t like this.
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,188
    Just discovered (and purchased) this asset. It looks amazing! This will make using Mecanim animations easy and fun again. Thank you!
     
    Kybernetik and elias_t like this.
  7. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Here's a quick progress update. v3.0 is basically feature complete now and I've prototyped about 20 new example scenes. Aside from polishing and documenting the examples, I have quite a long list of things to improve in the rest of the documentation, then I just need to make a trailer video to showcase the examples and redo all the asset store images. All up I'd estimate another month to get it all ready to release.

    One cool new feature I've added is serializables for each state type. So instead of referencing an AnimationClip directly, you can make a ClipState.Serializable field which contains an AnimationClip reference along with a fade duration, speed, and optional start time, all with a nice inspector. Then you can just pass that serializable into StartTransition and it will figure out whether to call Play or CrossFade based on the values you entered in the inspector. There are also AnimationMixer serializables which give you an inspector similar to setting up a blend tree and ParameterControllerState serializables which give you a dropdown menu for selecting the parameters you want to use once you assign an AnimatorController.

    If you're interested in trying it out, just PM or email me your invoice number. Or if you're using the Lite version, just let me know and I'll put a package together for it (which will take a bit longer). It's currently perfectly usable, the only issue you'd have to deal with is out of date documentation (and incomplete examples, though they are already way better than the ones in v2.0).
     
    elias_t and JoeStrout like this.
  8. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    If you would like to see the documentation in its current state I've put it up at https://kybernetikgames.github.io/animancer-v3/. I haven't gotten to most of the general pages yet, but the Examples are mostly done (up to 06 State Machines). Most of the examples should be fine to use in v2.0 with a couple of exceptions:
    • I haven't touched much of the general documentation, only the examples (and the Feature Comparison).
    • Some class names have changed. AnimancerController -> AnimancerComponent is the most notable.
    • "01 Basics/03 Sequence Coroutine" should be fine up to the last two sections where it talks about Serializables which are new in v3.0.
    • "01 Basics/05 Solo Animation" won't work because the Solo Animation component is new in v3.0.
    • The "04 Directional Sprites" examples require a new DirectionalAnimationSet class.
    • In "05 Animation Events/01 Simple And End Events" the End events won't work without v3.0.
    It's hard to say if it will be done within the two weeks or so left in my original goal. The example documentation should be done in the next few days, but then I still need to go over all the general documentation to make it relevant for v3.0 (I'll probably hold off on most of the actual improvements until after I get it released). Then the asset store images should only take a few days as well, but the main uncertainty is making the trailer video because I have no experience with video editing. That timeline also doesn't include the time it will take Unity to actually approve the update once I'm done, so that will probably add about a week (or more if it doesn't get approved on the first go).
     
    elias_t likes this.
  9. validname1

    validname1

    Joined:
    Feb 1, 2018
    Posts:
    23
    Question, what's the appropriate way to toggle animation looping via AnimancerState?
     
  10. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Depends a bit on what you actually want. If you just want it to freeze in place at the end of the animation you should probably just set the animation to not loop in the import settings. But otherwise you probably want to register an OnEnd callback.

    The v3.0 documentation explains it a lot better than the current v2.0 documentation. Here's the API page for AnimancerState.OnEnd and here's an example that shows it in action. Note that the Play method in v2.0 works like the PlayFromStart method the example talks about (it has changed in v3.0).
     
  11. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Edit: v3.0 is up on the store now.

    Well, it took a bit longer than expected to fully flesh out all the examples, but they're finally done. The last big hurdle before I submit to the Asset Store is to make a trailer video, which is something I have no experience so I don't know how long it will take (hopefully only a few days).

    In the meantime, I've decided to release an open beta so people don't have to keep waiting for the new features and so I can start getting feedback.
    • The beta documentation is hosted at https://kybernetikgames.github.io/animancer-v3/.
    • You can download Animancer Lite v3.0 from here (Edit: no you can't. Get it from the Asset Store). There are differences depending on your Unity version so you need to pick the closest one below the version you are using (if you are using Unity 2018.2 you need the 2018.1 package, not 2018.3). Details on the differences are in the documentation.
    • If you have purchased Animancer Pro, just PM or email me your invoice number and I'll send you the Pro version beta.
    • To install it, just delete any old Animancer version then import the new one. Don't forget to do a backup first. More info here.
    • If you have used Animancer before, check out the change log to see what's new.
    What now?
    • Once it's fully released, I'll overwrite the current documentation (same URL, but without the "-v3" at the end) so any links from inside the beta package won't work anymore.
    • In the meantime, lots of feedback would be great. Any problems you encounter. Things you have trouble figuring out. Suggestions for the plugin's functionality. Ideas for improving the examples or adding new ones. Anything I haven't explained well enough or have missed. Even little things I could improve in the layout or design of the documentation. Anything you can think of.
    • I'm also looking for some melee weapon animations so I can make an example to demonstrate weapon switching and hit boxes. They have to be public domain (CC0 license) so I can actually include them in the plugin (according to the Asset Store rules).
    • More feedback please.
     
    Last edited: May 27, 2019
    JoeStrout likes this.
  12. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    337
    Out of curiosity how is the performance when compared to Mechanim and does your asset generate any garbage? A couple of years ago I was working on a hoard shooter that used sprites and I found once I optimized many of the other aspects of the game, Mechanim itself became the biggest bottleneck. I was considering writing my own system from scratch but ended up moving on the bigger and better things. I'm considering revising this project for a gamejam that is coming up and I'd be interested to know how well this works when there are thousands of animated sprites on-screen.
     
  13. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    There's a simple Performance Benchmark in the documentation. Animancer is slightly better, but it uses the same underlying system as Mecanim to do all the heavy lifting so the difference will never be very significant.

    It doesn't produce garbage on its own, but it does encourage you to use OnEnd callbacks to wait for animations to finish and they will become garbage if you don't cache them.
     
    JoeStrout likes this.
  14. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Animancer v3.0 is up on the store now. Here are the major changes:
    • Replaced the 3 rudimentary demos with 22 proper Example Scenes that have highly detailed tutorial explanations.
    • Massively improved the documentation in general with lots of code examples and animated gifs.
    • Added serializable classes which make it easy to group additional details with each AnimationClip (such as Speed and Start Time), as well as set up Mixer States and Controller States in the Inspector.
    • Improved performance, especially in situations with lots of animations are inactive.
    • Added proper support for playing animations in Edit Mode. See the Fine Control/Doors example for a demonstration.
    • The full list of changes is available in the Change Log along with a guide for upgrading from earlier versions.
    Please check it out and let me know if you have any questions or feedback.
     
    BTStone, JoeStrout and elias_t like this.
  15. ZhavShaw

    ZhavShaw

    Joined:
    Aug 12, 2013
    Posts:
    128
    Can I change animation at runtime?
     
  16. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
  17. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    Hello, I'm trying to update to v3 and I'm running into an issue with AnimatorControllerState. That class seems to be gone, and I can't figure out how to add that controller state as a state to a AnimancerComponent.

    Also, how do I destroy a state attached to a AnimancerComponent?

    Thank you!
     
  18. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    AnimatorControllerState has been renamed to ControllerState. The full list of name changes is in the change log.

    You can destroy a state by calling its Dispose method.
     
  19. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    Ahh I see, I Ctrl-F'd it and couldn't find it cause the docs has a typo "AnimantorControllerState" should be "AnimatorControllerState" :) Thank you!

    How do I add a ControllerState to a AnimancerComponent? (Before I could "AddState")
    EDIT: Never mind, figured it out. :)
     
    Last edited: May 28, 2019
    Kybernetik likes this.
  20. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Thanks for letting me know. It's fixed now.
     
    joshcamas likes this.
  21. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    So sorry to keep bothering you, but now it seems my events aren't triggering :(
    The events are on a ControllerState. It's animating, 100% weight, etc. No events though

    Code (CSharp):
    1.  
    2. controllerState = new ControllerState(animancer.GetLayer(0), controller);
    3. controllerState.Play();
    4.  
     
  22. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    I'm not seeing any issues with animation events triggered by ControllerStates.

    What Unity version are you using? I tested in 2018.1.

    Go to the Animation Events/Other Events example and make sure it's working normally.

    If it is, make the following changes in the FootstepEvents script:

    public AnimancerComponent animancer;
    public RuntimeAnimatorController controller;

    private void Awake()
    {
    var state = new ControllerState(animancer, controller);
    animancer.Play(state);
    }

    Then create an Animator Controller, drag in the Humanoid-Walk-Footsteps clip as its default state, and assign those new references in the Inspector.

    Let me know if it works like that.
     
  23. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    The original example worked, as does the one with changes.

    Turns out running state.Play() doesn't trigger events, but animancer.Play(state) does. Is this on purpose?
     
  24. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    I see the problem now.

    Layers all start at 0 weight by default.

    Calling Play on the AnimancerComponent / AnimancerPlayable / AnimancerLayer when the layer is at 0 weight sets it to 1.

    But calling Play on an individual state doesn't affect anything other than that state so it won't stop anything else from playing or change the layer weight.

    So your state was at 1 weight, but the layer was still at 0. It seems that the internal AnimationLayerMixerPlayable decides to completely ignore the weight when there is only one layer connected but the Animation Event system still checks the weight properly so you see it playing but its events don't get fired. I'm going to report that as a Unity bug.
     
    joshcamas likes this.
  25. spacefrog

    spacefrog

    Joined:
    Jun 14, 2009
    Posts:
    561
    Great package, i'm pretty impressed with Animancer, though i havent used it for more than an hour ...
    One thing though i noticed is that events sitting at the very end AFTER the last keyframe do not trigger most of the time ( tested on spriteanims using PlayAnimationsInSequence() on a NamedAnimancerComponent ).
    All other events trigger just fine ( at start, and during the whole animclip timespan ).
    It's just the end event that sits after the last keyframe that doesnt fire
    So the fact that there's an event after the last keyframe is worthy of discussion, though i previously had those animations controlled by mecanim, and mecanim fires those events just fine. And i have a lot of anims that are set up this way ( arround 1.5k )
    BTW: Same was true for the pre V3.0, but still is true for the recently released V3 version ...
     
    Last edited: May 31, 2019
  26. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Thanks, I'm glad you like it.

    That's an odd issue. I just did a quick test and found such events to work perfectly fine. There shouldn't be much room for such a bug because Animation Events are handled entirely by the Playables API without any direct contact with Animancer so Mecanim should work exactly the same because it uses Playables as well.

    I assume events within the animation timeframe work fine?

    Which Unity version are you using?

    Have you checked the layer weight in the Inspector in case it's the same issue @joshcamas just had a few posts ago?
     
  27. ikemen_blueD

    ikemen_blueD

    Joined:
    Jan 19, 2013
    Posts:
    312
    @Kybernetik quick question for ya, how easy to switch between Root Motion ON & OFF? I often want Root Motion ON when attacking, and OFF when walking. Thanks.
     
    hopeful likes this.
  28. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    I don't use root motion much myself, but it should just be a matter of setting the applyRootMotion property via the AnimancerComponent's reference to the Animator. I.E. animancer.Animator.applyRootMotion = ...
     
  29. ikemen_blueD

    ikemen_blueD

    Joined:
    Jan 19, 2013
    Posts:
    312
    Can you do an example scene about it? It sounds a bit confusing to me. I think it would be useful for others as well. Thanks.
     
  30. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    Is there a way to detect when a clip / controllerstate has faded out during a crossfade? (Completely faded out)

    EDIT: I guess one way is to check every frame if the weight is at 0
     
  31. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    @ikemen_blueD Something like this:

    Code (CSharp):
    1. [SerializeField]
    2. private AnimancerComponent _Animancer;
    3.  
    4. [SerializeField]
    5. private AnimationClip _Walk;
    6.  
    7. [SerializeField]
    8. private AnimationClip _Attack;
    9.  
    10. public void Attack()
    11. {
    12.     _Animancer.Play(_Attack);
    13.     _Animancer.Animator.applyRootMotion = true;
    14. }
    15.  
    16. public void Walk()
    17. {
    18.     _Animancer.Play(_Walk);
    19.     _Animancer.Animator.applyRootMotion = false;
    20. }
    Here's a more complete example which uses a custom serializable so you can specify whether you want root motion alongside each animation in the inspector along the same lines as the Basics/Sequence Coroutine example.

    @joshcamas when an animation fades out it gets stopped so you could also check its IsPlaying flag, but yeah, checking something every frame is pretty much the only way to do it.
     
    ikemen_blueD likes this.
  32. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    Is there a way to make "container" states? Aka states inside of states?
     
  33. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Mixers could be considered "container" states along the same lines as sub-state machines in an Animator Controller. What are you actually trying to achieve?
     
  34. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    I think I might be able to use the mixer.

    I'm wanting to build my animator to have a higher up state machine that has 3 states: "base", "weapon", and "dead".

    Each state has its own complex logic on what should happen when that state is entered. And I feel like having them in a container of sorts makes things a lot more modular - especially since different states may have different layers and stuff.

    In other words, imagine each state being a ControllerState. But instead of a controller asset, its a... controller built from animancer.
     
  35. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    That sounds like you need a separate state machine system like the one demonstrated in the State Machines examples. "Dead" is just an animation, but "Weapon" isn't an animation, it's a complex state (or group of states) in your state machine system which involves several animations. So there isn't really any reason for the animation system to know about the "Weapon" group, only about the specific animations that actually need to be played.

    Yeah, that's pretty much what Mixers are, though all the included ones are geared towards acting like Blend Trees except for ManualMixerState which just lets you control all its children manually. If you do want to take that approach, it should have pretty much everything you need except for Play and CrossFade methods (because all other mixers inherit from manual and it doesn't really make sense to have those methods in any of the others). You could easily create your own subclass and add the methods you need though (you could probably just copy them straight from AnimancerLayer).
     
  36. LukeDawn

    LukeDawn

    Joined:
    Nov 10, 2016
    Posts:
    335
    This is one of those secret gems on the store that just makes life easier. Top work, @Kybernetik
     
    hopeful, joshcamas and Kybernetik like this.
  37. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    I just reread your post and saw this. PlayAnimationsInSequence will stop each animation when it reaches the end to play the next animation, so any events after the last keyframe will not trigger unless the last frame that was rendered had enough delta time to jump the animation past both the end and the event in question in one go. So I would expect that to sometimes trigger events that are right after the end and sometimes not.
     
    spacefrog likes this.
  38. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    729
    Does this system get along well with an already-working animator controller? For example, some other store asset has a big hairy machine graph that's 99% working the way I want it, but they forgot to insert a few little things like reach-for-doorknob actions. I could try to figure out how to use Unity's PITA machine editor, or I could just play a separate animation on my own with code and then let it resume control.
     
  39. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    I haven't done it much myself, but that sort of thing can be achieved with ControllerStates.

    There aren't currently example scenes that show exactly what you're looking for, but the Locomotion/Linear Blending example shows how to play a controller containing a Blend Tree and it should be pretty easy to see how to play separate animations as well like any of the other examples. Feel free to ask if there's anything you can't figure out.

    I'm planning on making a new example scene to show how to use controllers like that (and a few others) once I'm done with Inspector Gadgets v6.0. I don't have a solid release date planned yet, but I expect it to fall within 1 to 2 months.
     
    ikemen_blueD and hopeful like this.
  40. spacefrog

    spacefrog

    Joined:
    Jun 14, 2009
    Posts:
    561
    Thanks for keeping this up-to-date ...
    your analysis sounds plausible , will keep posting new findings as soon i'm back dealing with animation stuff again
     
  41. KristianF

    KristianF

    Joined:
    Jul 19, 2012
    Posts:
    11
    Hey, I have a performance related question.

    Does anyone has comparison/experience of Animacer Pro vs Animator in a scene were you can have around two hundered units on screen?
     
  42. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
  43. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    (Not super important) request: Add a CrossFade for clip input, instead of just state
     
  44. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
  45. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    I'm stupid, sorry - I meant for AnimancerLayers.
     
  46. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Unfortunately that wouldn't fit in with the way the system is currently set up. The method I just linked uses AnimancerComponent.GetKey(clip) to determine what to use as the dictionary key (the clip by default, but NamedAnimancerComponent overrides it to use the name string instead). But states and layers don't have any reference to the AnimancerComponent so they obviously can't call that method.

    I could of course simply give the root AnimancerPlayable a reference to the AnimancerComponent so all states and layers can access it, but that would create an otherwise unnecessary coupling between those classes which doesn't sit right with me when all it adds is a minor convenience overload.

    I'm open to discussion though. What does your code currently look like that this would simplify?
     
    joshcamas likes this.
  47. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    That's fair enough. I've simply made a higher level function that deals with it, and figured that it would make sense to have it in the layer level. But if it creates a unnecessary coupling then I don't think that's worth it at all. :)
     
  48. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    is there a way to remove a animancerLayer from a animancerComponent?
     
  49. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    540
    Reducing the LayerCount will destroy any excess layers.
     
  50. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    815
    It would be super amazing if it was possible to easily replace combining controllers entirely. Ik it's possible to easily replace a single controller, but trying to replicate cross fading between two controllers while maintaining modularity is extremely hard. I've been trying to wrap my head around how I could do this for months now :(

    When using controllers:
    -play(controller1)
    - crossfade(controller2)

    When using pure code:
    - setup "codified" controller1 (easy)
    - manually fade and do everything needed to crossfade things correctly

    Does this make sense? Or am I simply approaching this entirely wrong?