Search Unity

[Released] C# Animator

Discussion in 'Assets and Asset Store' started by CSharpAnimator, Feb 8, 2019.

  1. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Hey guys, I've just released the first version of C# Animator to the asset store!

    Asset Store Link

    I developed C# animator while working on a relatively large commercial game a couple of years ago. The problem I was trying to solve was designing and maintaining large animator assets. I found some simple things missing from the animator window, such as copying and pasting state transitions, or the ability to transition from many states to another without duplicating the same transition multiple times.

    I solved this problem by writing what I think is a nice C# interface for generating animator assets:

    Code (CSharp):
    1.  
    2.         ParameterData speed = FloatParam("Speed", 1.0f);
    3.         ParameterData jumpTrigger = TriggerParam("JumpTrigger");
    4.      
    5.         Animator
    6.         (
    7.             Graph()
    8.             [
    9.                 Layer("Base").DefaultState("Idle")
    10.                 [
    11.                     State("Idle", idleMotion),
    12.                     State("Run", runMotion),
    13.                     State("Jump", jumpMotion)
    14.                 ]
    15.             ],
    16.  
    17.             Transitions()
    18.             [
    19.                 Transition().SourceMultiple("Idle", "Run").Destination("Jump")
    20.                 [
    21.                     Trigger(jumpTrigger)
    22.                 ],
    23.                 Transition().Source("Jump").Destination("Idle").ExitTime(0.9f),
    24.  
    25.                 Transition().Source("Idle").Destination("Run")
    26.                 [
    27.                     Float(speed, speedForRun, ConditionMode.Greater)
    28.                 ],
    29.                 Transition().Source("Run").Destination("Idle")
    30.                 [
    31.                     Float(speed, speedForRun, ConditionMode.Less)
    32.                 ]
    33.             ]
    34.         );
    Using C# to generate animators, and more generally, using text, creating complex animation state machines has become a non-issue for me. States and transitions can be easily moved, copied, reference, and mass generated. Also, given that this code is part of your game project, the animator can directly reference constants used for gameplay. For example, your character controller may have a list of states described as an enum. Using this asset, you can reference the same state enum used to drive your gameplay logic to determine your transition conditions, meaning the animator and gameplay logic will never get out of sync!

    A big goal of this tool is to be as easy as possible to integrate. The bare minimum for the tool to function is to import "CSharpAnimator.cs". Optionally(recommended), you can import "CSharpAnimator_Class.cs".

    In order to create an animator generator class, you simply need to derive from either "CSharpAnimator" or "CSharpAnimator_ClassBase". deriving from CSharpAnimator requires the class to have it's own file, where the filename matches the class name(because it works like a scriptable object), deriving from CSharpAnimator_ClassBase will not have this restriction.

    Once the class is made in C#, the animator asset can be created through the Assets/Create menu. Then just press the generate button in the animator's inspector.

    Here's a small example of how this works:


    Complete example code with comments:
    Code Examples
    Introduction Document


    C# Animator also comes with full source code.
     
    Last edited: Mar 30, 2019
    XCPU, JBR-games, StevenPicard and 5 others like this.
  2. FlorianBernard

    FlorianBernard

    Joined:
    Jun 9, 2015
    Posts:
    101
    This looks amazing. I will definitely give it a try next time I need to deal with Animator!
     
    CSharpAnimator likes this.
  3. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Thank you!

    I'm curious though, is there a way you typically avoid dealing with the animator in Unity when you need to animate things?
     
  4. FlorianBernard

    FlorianBernard

    Joined:
    Jun 9, 2015
    Posts:
    101
    There's not! I mean at least I don't know any other way :)
    But now I do thanks to you!!
     
    CSharpAnimator likes this.
  5. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    598
    Sorry i havnt looked into this to far yet, but does this allow a person to build the animator through script ?
     
  6. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Yep. You write a C# script that describes the graph and transitions. Then you can press a button on the animator's inspector to generate the animator asset.
     
    JBR-games likes this.
  7. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    598
    Can you use this to update or change an existing animator?
     
  8. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    You can regenerate the animator any time you change your script to update it. But you can't take an animator made using the animator window and work from that. If you have an animator that you made using the animator window, you'll have to rewrite it in C# Animator and then generate it to start working on it in C#.

    EDIT: Hope this is making sense. Let me know if it doesn't. Overall the general work flow is:

    Write C# code -> Generate asset -> Update C# code -> Regenerate asset -> etc.
    Every time that you generate the asset, any edits made in the animator window(besides the positions of the state nodes) are overwritten with the C# animator settings.
     
    Last edited: Feb 14, 2019
    JBR-games likes this.
  9. XCPU

    XCPU

    Joined:
    Nov 5, 2017
    Posts:
    125
    Given the generator part, was wondering, could the Code just be deleted after generation,
    and use the Animator window to make changes\tweeks forever after?
    Thinking of Builds and excess code in a project,
    seems like a nice way get the majority of an Animator started, for a programmer anyways.
     
    JBR-games likes this.
  10. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Yeah you could delete all C# Animator code(both your code and the plugin), and the animators will function like normal. It just outputs a Unity animator asset. All C# Animator code and all code that use it must be editor only, so it won't be left in builds anyway.

    One small difference is that the C# Animator scriptable object will be left as a sub asset of the animator asset. This shouldn't make any noticeable difference at all though. I am thinking about ways to avoid this still, though.

    But yeah, essentially you can write the code, generate once, and then just work directly in the animator window like normal.
     
  11. XCPU

    XCPU

    Joined:
    Nov 5, 2017
    Posts:
    125
    Excellent, sounds like a good option.
     
    CSharpAnimator likes this.
  12. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    If you end up using C# Animator, let me know if you have any problems with this or anything else. Thanks!
     
  13. JBR-games

    JBR-games

    Joined:
    Sep 26, 2012
    Posts:
    598
    I think im going to pick this up soon... Any docs i can look over ?
     
  14. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Awesome!

    Only a document going over some of the stuff you can achieve with it. It comes with the package, but I'll update my initial post with the link:

    Here it is:
    https://pastebin.com/p8axC6K6

    I suspect you mean something more along the lines of an API reference though. Personally I find looking at examples and source more effective. Is an API reference something you would find useful?
     
  15. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    Hi, I'm interested in this asset but I have existing Animator. Can it generate C# from Animator? If possible, it will become a very powerful tool and full Round-Trip is allowed. Thanks.
     
  16. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Hey chrisk! C# Animator doesn't generate C# from an existing animator asset, unfortunately. I don't plan on adding this either. If I was in your situation and I wanted to use C# Animator, I would probably just write it out from scratch. In my experience writing C# to generate animators is pretty fast, even if you're recreating fairly large animators(I did this when I first created the tool).

    It's an interesting idea. I think being able to generate both ways would create a few problems, though.
     
  17. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    Is this because it's impossible to implement? I prefer editing C# but for a simple tweak and testing, working on Animator directly would be more intuitive. Force to edit in C# and generate all the time will probably stop many onlookers to adopt your asset. Unless it's impossible to do so, please consider adding the full round-trip support. Thanks.
     
    JBR-games likes this.
  18. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    I don't think it's impossible(depending on what you're asking about), but there's a few problems I can think of straight away. For example, if you create a C# animator, generate the animator asset, edit the animator asset, then you generate C# from that asset. In this case what happens to things that you have written in C# that can't be described in an animator. For example, you could use a loop in C# to generate a variable amount of states, or you could write a few comments.

    Basically, from my understanding, given an animator asset, there's an infinite set of C# snippets that could generate that asset. So, if we're talking about a full round trip on any change in the animator, then it's not possible to avoid potentially losing work on the C# side.

    It could be possible to read some stuff back for tweaking, like I already do for the position of nodes in the animator graphs, but again this seems tricky. What if that value you're tweaking was a constant in C#? When you generate C# code, will it stomp that constant with a literal value?

    You can currently tweak stuff in the animator, though. It's just that when you go to generate, all those changes will be lost. You might find some value in tweaking the animator asset directly until you get the right values, then replicating those values in C# manually, but depending on how much you do this, it might be error prone and tedious.
     
  19. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    Yeah, it's not easy to support full round-trip but I'm sure you understand that tweeking/testing in Animator has some value.
    I guess what we need is a text representation of Animator and it doesn't even have to be c#.
    It might be easier to have Animator DSL and we can use that to generate Animator and Animator to generate DSL.
    If it's possible, really great, if not, I'm not really sure what the true benefit of this asset is. One benefit I can think of is that I can diff the changes and merging two different Animator into one more easily.

    And having a DSL can have another benefit. We can probably support Animatable if we want. I think Animatable will be the future Animator since it will be based on ECS and run parallel jobs.

    Something to think about. Thanks.
     
    CSharpAnimator likes this.
  20. Ooi

    Ooi

    Joined:
    Nov 22, 2015
    Posts:
    11
    It'll be easy to do a full-round-trip if everything is done in markup languages like HTML/XML. But yeah... C# gives you more control especially when you want to add multiple animations by parsing asset names. Or generate the Animator assets more dynamically.

    EDIT: Just went and checked the Animator file. It's just purely written in YAML and looks like hell. Let stay with C#.
     
  21. kjhuebner

    kjhuebner

    Joined:
    Oct 2, 2018
    Posts:
    11
    Hi Ben, How can I go about creating a Unity mecanim transition from the Unity standard "Any State" to a custom state with your C# Animator tool?

    I tried various function calls Source() or SourceRecursive() on various state labels, including "Any State" without any luck. Clicking on Generate button does not generate a transition from Unity's "Any State".

    Transition().SourceRecursive("Any State").Destination(STATE_JUMP)
    [
    Trigger(jumpTrigger)
    ],

    Ken
     
  22. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    @kjhuebner

    Really sorry for the late reply, I didn't get an email about this post.

    Anyways, until now there was no way to do this. In my experience the features that C# Animator provides makes the "Any" node redundant. If I'm not mistaken it's functionality can be replaced with SourceRecursive.

    Either way, I've had a couple of people request it now(and the "Exit" node) so I've gone ahead and added it and have submitted a new version of the asset for review. It should be available in a couple of days I assume.

    Your example would be:

    Code (CSharp):
    1. Transition().Any().Destination(STATE_JUMP)
    2. [
    3.     Trigger(jumpTrigger)
    4. ],
    And Exit would be the following:

    Code (CSharp):
    1. Transition().SourceSingle(STATE_JUMP).Exit()
    2. [
    3.     Trigger(jumpTrigger)
    4. ],
    Just as a random example. Also, in case it's not obvious, "Any" as a destination is not allowed and "Exit" as a source is not allow. Also "Any"->"Exit" is not allowed since Unity's API doesn't seem to allow it(would that even make sense anyway?).

    I hope this solves your issues. Let me know if you have any more questions and once you get the update, let me know if I broke anything.

    Thanks!
     
    JBR-games likes this.
  23. kjhuebner

    kjhuebner

    Joined:
    Oct 2, 2018
    Posts:
    11
    Your updated Csharp Animator 1.0.2 release available at Unity store looks good. Thanks for implementing the "Any State" feature! I tested using the new "Any State" transitioning to a custom state with both a trigger and a float speed threshold and both mechanisms worked fine.

    I've found the "Any State" can simplify some mecanim graphs.

    Thanks again!
     
  24. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    Hi, is there a list where this asset currently does not support Animator features?
    For instance, I don't see any mentioning of BlendTree. Is this being supported?

    I think this asset has great potential and I hope it to completely create Animator using code only.

    Thanks.
     
  25. kjhuebner

    kjhuebner

    Joined:
    Oct 2, 2018
    Posts:
    11
    Chrisk, I purchased CSharp Animator about a month ago. Blend trees are supported. I've used the tool to build mecanim graphs with 20+ states and 40+ transitions including an Idle blend tree state. Took me about an hour to make, and I can replicate the code to make more custom animator controllers. CSharp Animator is a remarkable tool that I cherish. I cannot imagine implementing the same thing using Unity's built-in mecanim design tool.
     
  26. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Hey chrisk,

    There's no list of features that this asset does not support. Unless I'm missing something, the recent inclusion of the "Any" and "Exit" nodes was the last things in the Animator UI that it was missing. The only thing I could list is the "compute positions" and "adjust time scale" functionality found in blend trees, just because I couldn't find any helpful documentation at the time I believe.

    Here is some code examples you may have missed:
    https://pastebin.com/uCdveqXr

    This has a blend tree example. Let me know if you want any more information on any specifics.
     
  27. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    Ah, that's awesome! thanks.
    I mentioned it has great potential because it has a good chance to become a new way to work with animation.
    Animator IDE better fit for debugging and fine-tuning and the Code for the designing.
    Here are the reasons why I think so.

    1. Animation often directly tied to game logic. Therefore it's better if a programmer can layout the animation.
    2. For debugging, we need visualization tool and I think Animator IDE is still very useful.
    3. And for fine-tuning, I think it's animator's job to work on such as timing and so on. This is often outside of programmers' job and I think this is where the round-trip is important so that our animators does not have to depend on our programmer to update the animator with minor changes. I hope you can see why I asked for the roundtrip so that our programmers and animators can work independently. I know that supporting roundtrip is not easy. It may require a special DSL but it's worthwhile thinking about it.

    Anyway, besides the roundtrip, here is something interesting idea to think about. Animator diagrams can get out of hand easily when you have multiple weapons. Unity has something called "Animator Override Controller" to replace certain animations at runtime, but it has some problem swapping the animation during runtime. Swapping animation during runtime is also called Animation Injection, and I'm wondering if you have thought about a way to do this properly. If we can support Animation Injection, it will simplify the animation setup quite a bit. And I think it can increase the value of this asset by a huge factor.
    Here is a link to explain what I'm talking about and please let me know what you think.
    https://connect.unity.com/p/articles-animation-injection

    Cheers!
     
  28. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    The intent of CSharpAnimator is that the graph only is described by code. Any animations or timing data can be exposed to the editor and changed on a per animator asset basis. This basically separates the graph from what it plays, and in my experience this makes animator override controllers redundant. So as long as you expose all the necessary data to the editor, artists should be able to fine-tune timing and other parameters. They won't be able to modify the layout of the graph, but as you mentioned gameplay logic is often dependent on the graph's layout anyway and can't be freely changed.

    In the article that you linked, wouldn't the problem be solved by just using one animator asset per character? This way you can tweak each one and link up the character specific animations. The obvious draw back is the work involved in duplicating those animators and this is exactly what CSharpAnimator solves. My approach would be to write code to generate only one graph then link up animations for, tweak, and generate one asset for each specific character.

    Regardless though, I'm not interested in ever adding runtime functionality to CSharpAnimator. One of it's strengths is that it shouldn't have any affect on the code that you ship, and is only there to generate data at edit time. I think this tool is so useful partly because it's goal is extremely focused.
     
  29. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    The problem is that the artists' tuning data are lost when the layout changes. It will be very difficult to bring the changes back to the code because the programmers don't know what changed.

    Have you dealt with a large animation graph? Without Animation Injection, you will have to manage the big gigantic mess as you progress.
     
  30. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    If you expose data to the inspector using [SerializedField] and use that data when generating the graph, then those changes will stay. If the artist changes the graph itself, then yeah those changes will be lost. Artists can't freely modify the graph itself, but they can change data that you've exposed in the inspector.

    I have dealt with rather large animation graphs that were shared between multiple characters in the past for a commercial game, and yeah it's a very big problem. That's why I created this tool, and it's pretty much solved the problem for me in the way that I described in my last post. The team I was on only ever had the programmers deal with the animator graph anyway, so artists weren't doing a lot of tweaking.
     
  31. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    Thanks, and I would like to ask one more thing.

    Is it possible to add additional information to the existing Animator without completely overwriting it?
    I'm asking this because I already have Animator and I would like to keep it as is and just add new information using this Asset. The existing Animator is already pretty complicated and it will be very difficult to port to C# Animator. If Roundtrip is supported, I don't have to worry but it doesn't look like we will have it soon.

    Let say, I want to add a new state to an existing layer. Will I be able to just type the new state and this state will add on top of the existing Animator. If the same state exists, it will replace it with the new state, of course.

    Thanks.
     
  32. kjhuebner

    kjhuebner

    Joined:
    Oct 2, 2018
    Posts:
    11
    From what I've noticed, adding a new state,etc in C# Animator and RE-GENERATING the animation controller will create a wholly new controller graph -- with the new state.

    However, any adjusted and serialized data that was saved in the previous controller graph is LOST... and overwritten with default values upon "re-generation".

    Strangely, the one thing that does NOT change is the visual layout of the graph in the Unity mecanim design tool. I can add states, re-generate the graph, and the original layout in the design tool remains intact. Very odd behaviour. But if this did not occur, the tool would be horrible to work with as one would always have to re-layout the visual design over and over again on "re-generation".
     
  33. kjhuebner

    kjhuebner

    Joined:
    Oct 2, 2018
    Posts:
    11
    Ben, I'm not sure if you are a regular Unity developer... but do you have any insights as to how C# Animator will be supported in future versions of Unity?

    So far, the Unity mecanim API seems fairly stable.

    But Unity 2019.3 was just released. Does C# Animator work with latest version?

    Thanks,
    Ken
     
  34. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    There's currently no functionality to convert existing Animators or generate any C# code of any kind. You will need to start the animator from scratch in C#.


    Yeah this is a special case where the tool will save/remember positions of states with the same name so you don't have to layout everything again. This makes me think that states/statemachines in general can be serialized and have all their information transferred over. I don't know if this is a good idea though, since it'll be very unclear what is saved and what is lost.


    I'm currently not using Unity at all, so I'm not checking new versions regularly. Like you said, the API seems stable and I've yet to have any problems since initial release. If anything was to break, I'd expect it to be the custom inspector code since a lot of that functionality didn't have much documentation. I can check 2019.3 and get back to you.
     
  35. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    I know, that's why I asked if C# Animator can add stuff additively to an existing Animator without regenerating everything.
     
  36. CSharpAnimator

    CSharpAnimator

    Joined:
    Feb 5, 2019
    Posts:
    19
    Yeah, currently not. The entire animator is recreated every time you press "generate", the only thing that persists is node positions. That seems like it could be possible to implement, though.
     
  37. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    640
    That will be nice. It will enable us to use existing Animator then. Please let us know when it's supported. I'll be looking forward to it. Thanks.
     
unityunity