Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Animancer - Less Animator Controller, More Animator Control

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

  1. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
    You mentioned that it's easy to sync animation layers, how would we set about doing this? Would this be done by changing the speed of the layer so that the end time matches the base layer end time perhaps?
     
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    If you are mirroring every base layer Play call with one on the synced layer, you could get both the states and set syncedState.RemainingDuration = baseState.RemainingDuration, which should avoid the need to figure out the correct calculations to accommodate the end times of each state.

    Doing that whenever you play something might be enough, but if they are playing for long enough that floating point error causes them to gradually get out of sync you could simply do it every update.
     
    andreiagmu and craigjwhitmore like this.
  3. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    So how can I do it then to set the speed of the Animator Controller?

    Ok, just saw the work around... Im sure there must be a better way, probably you can systematically implement the workaround behind the HybridAnimancerController an just expose a speed setter. Isnt that possible?
     
  4. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    That would require modifying the Animator Controller in the Unity Editor, probably costs some extra performance, and would interfere with a Speed parameter you were using for a different purpose so it definitely shouldn't be done automatically.

    It would be pretty easy to implement as a context menu function you can run on an Animator Controller asset or maybe add it as a panel in the Animancer Tools window.

    Off the top of my head I can't think of a good way to automate it, but it's worth some more thought. For example, if I put a toggle in HybridAnimancerComponent and you have two of them referencing the same Animator Controller with different values, they would conflict with each other.
     
  5. Cachete

    Cachete

    Joined:
    Jul 4, 2017
    Posts:
    3
    Hey. I'm using Animancer for animation and I'm a Unity newbie - tho I work as a software developer, so I know something about programming at least. :p
    Is it that all animations played with animancer (e.g. animancer.Play(jumpAnimation)) loop indefinitely or am I missing something? How to prevent the looping?
    Thanks in advance.
     
  6. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Animations will only loop if their Loop Time toggle is enabled, otherwise when they reach the end they will freeze in place. If you want to do something else after an animation, End Events are a good way to achieve that.
     
  7. manurocker95

    manurocker95

    Joined:
    Jun 14, 2016
    Posts:
    209
    It would be good to be able to loop specific transitions without modifying the clip loop parameter.

    Btw, v6.0 (beta 2) works like a charm.
     
  8. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    You could use an End Event to set the time back to 0, but it would not be a smooth loop because any time past the end would be lost and it would stay at 0 for that frame instead of advancing normally. There isn't really a way to properly make animations loop without setting it on the asset.

    If you mean v6.0f2, that's Release Candidate 2 which is the exact version I uploaded to the store so if you got that then you don't need to bother updating from the store as well (unless you leave a review, then it shows everyone the version you are using so I guess you might as well be using the latest).
     
  9. manurocker95

    manurocker95

    Joined:
    Jun 14, 2016
    Posts:
    209
    What a shame as you can't modify .asset in runtime. I guess the best bet then is having the animation duplicated one with loop and the other without it.

    Oh, yep, that one. I left a review with 5.3 version, iirc.
     
  10. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    Hi,

    I was just having a little trouble adding a parameter into an end event.
    Code (CSharp):
    1. anim.Play(landMix, 0.025f).Events.Add(new AnimancerEvent(0.25f, BlendToBase(1.2f)));
    2.  
    Is there a way to use a parameter for the "BlendToBase" method in this example? I was struggling a little to find an example of that in code.

    Thanks,
    Pete
     
  11. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
  12. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    Hmm, but that example doesn't seem to use parameters in the method, am I missing something there? Might be a little beyond me :)
     
  13. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Yes it does, it passes a string into Debug.Log just like you want to pass a float into BlendToBase.

    All you need is
    () => BlendToBase(1.2f)
    so that you are giving the event a lambda expression that can be called later on instead of calling BlendtoBase now and trying to pass its result to the event.
     
  14. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    But can that be used with Events.Add? Or does it have to be registered in Awake, then reused later with that parameter value?
     
  15. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Yes, you can just add the
    () =>
    to the code you posted.
     
  16. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    Ahhh, thanks for sticking with me there :D That's great :)
     
  17. frostymm

    frostymm

    Joined:
    Jun 21, 2013
    Posts:
    34
    Howdy, I've run into an issue with the fadeDuration. I've got an idle animation and it's set to play with a fade from whatever it's currently in. I run into the issue when trying to play the animation that it's fading from again. For example, I've got an attack animation StrongAttack and what I do is this:

    StrongAttack -> fade to idle -> StrongAttack immediately (within the fade duration) -> entire model freezes up for the duration of the StrongAttackAnimation, eventually returns to idle.

    Everything works appropriately without fadeDuration set but it looks kind of janky. Is there a way to get around this?

    Edit: Currently on the latest animancer in Unity 2019.4.12(LTS)
     
  18. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Go through the Playing and Fading example if you haven't already. I haven't seen the exact behaviour you're describing, but that example covers the most common issues with fading.

    Otherwise, pause the game and step through it frame by frame with your character selected so you can see what is actually happening in the Inspector.

    If that doesn't help, can you post your code so I can take a look at it?
     
  19. frostymm

    frostymm

    Joined:
    Jun 21, 2013
    Posts:
    34
    Well I couldn't replicate the behavior using the example scene BUT adding FadeMode.FromStart did fix my problem! Thanks a bunch! The documentation made it pretty easy to understand what was happening.
     
  20. salepaun

    salepaun

    Joined:
    Dec 19, 2016
    Posts:
    3
    Hi,
    Is there an easy way to copy the current state from one AnimancerComponent to another?
     
  21. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    There's no inbuilt method to copy the details of one state onto another, but it would be easy to make one.

    It should also be possible to move a state from one AnimancerComponent to another, though I've never actually had a reason to test it.

    What are you trying to achieve?
     
  22. salepaun

    salepaun

    Joined:
    Dec 19, 2016
    Posts:
    3
    I am trying to simulate my character in the future, based on the current input and state. For that, I would need to be able to copy the state of my character to the character used for prediction and then simulate it.
     
  23. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    You can use foreach loops to go through every state in every layer so if you only have basic ClipStates to play individual AnimationClips you could just create the same ones on the predictor character and copy over the details you want. Needing to support other state types like mixers would be more complicated though, so that might be something I need to look at for the next version.
     
  24. MSavioti

    MSavioti

    Joined:
    Dec 27, 2017
    Posts:
    4
    Hi @Kybernetik !

    I wanted to know if transitions are compatible with non-loopable animation clips.

    If it helps to know, we're trying to build a combo system around a single transition and we're having trouble to get the animations played, as they get stuck at the final animation frame.
     
  25. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Transitions don't care what happens when a clip ends, they simply define how it is played.

    End Events are very useful if you want to do something when an animation ends (such as play a different animation).

    Also, the Weapons example demonstrates a simple combo system that you might find useful.
     
    MSavioti likes this.
  26. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    G'day! Hey just wondering. Is there a way too create an AnimancerEvent that starts at a time offset other the clip's own normalised time?
    For example, I have a clip I'm using as a single pose (so it's only 2 frames long) and I'd like to create an AnimancerEvent that starts, 0.5 of a second after it plays. Is there an easy way to set that up with animancer events?
    Screen Shot 2021-01-14 at 5.44.18 pm.png
    Thanks!

    EDIT - I realised I can use the clip.length like this :
    anim.Play(clip1, 0.15f).Events.Add(new AnimancerEvent((0.5f)/clip2.length, () => Air(0.25f)));
     
    Last edited: Jan 14, 2021
  27. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Yep, that's correct.
     
    petey likes this.
  28. neo-mashiro

    neo-mashiro

    Joined:
    Aug 7, 2020
    Posts:
    19
    Hello, what's the difference between a normal Animancer Event and an End Event? I've read the documentation but still feel a bit confused. Since the End Event can be triggered at any time by setting a transition's End Time without affecting playback, it seems to me that those events are equivalent. As I understand, I can just always use the End Event if I only need one event, is there any case when an Animancer Event is superior and favorable?

    btw, I was following the "Idle" section in the "3D Game Kit" example, there's one main idle animation and several random idle animations to switch to. I copied the exact same code, but the End Event of the random animations never get triggered. I spent 2 hours tracking down the issue everywhere in my script, and finally found the reason:

    Code (CSharp):
    1. [SerializeField] private ClipState.Transition[] _RandomAnimations;
    In the inspector, this serialized field has an initial size field of 0, when I entered a number such as 2, two transition fields named "Element 0" and "Element 1" appeared below. Then I set up the animation clip and fade duration, but I didn't realize that the default value of "Speed" is 0x, so that as soon as the random animation is played it freezes on the first frame. As an improvement, I think we can change the default Speed to 1x, in case someone didn't notice it.... All other transitions already have a default Speed of 1x, only the elements in a transition array is 0x by default.
     
  29. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    The dot points on the End Events page explain the differences. The main one is:

    "Where other events are only triggered once when the specified time passes, End Events are triggered every frame after that point. This ensures that even if the animation has already passed the end when you register the event, it will simply trigger next frame instead of not triggering at all and probably leaving the character stuck in that state."

    So if you only need one event which will play something else, then there's little difference between them in most cases.

    That speed issue is caused by Unity's Serialized Array Initialization bug which I thought I had fixed, but it's broken again in the current version. If you have Animancer Pro, I've posted a simple fix here.
     
    hopeful and neo-mashiro like this.
  30. neo-mashiro

    neo-mashiro

    Joined:
    Aug 7, 2020
    Posts:
    19
    That's very helpful, thanks a lot!
     
  31. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    I just replaced those dot points with a table so it should hopefully be a bit clearer now.
     
    neo-mashiro likes this.
  32. neo-mashiro

    neo-mashiro

    Joined:
    Aug 7, 2020
    Posts:
    19
    Yes it looks much cleaner, nice work!
     
  33. Marsunpaisti

    Marsunpaisti

    Joined:
    May 3, 2018
    Posts:
    22
    So I've been looking into this asset because I would like to swap animation sets for my character depending on equipped weapons (Dark souls style). There seems to be a lot of useful stuff but I need to be certain that there is this one thing I need.
    I tried to look for solutions to the problem that I have in my mecanim animator, which is that I cant just use animation override controllers with different clips because the combinations of attacks might be different so I have to be able to swap in transitions too (For example jump -> heavy attack transition might look good with one clip and a given exit window&fade but not with another). Can I somehow create an "animation set" that I plug into my animator that not only specifies new animations but also precisely specifies the transitions between those new clips? For example being able to completely switch out a sub state machine from my controller to a newly equipped weapons state machine at runtime would accomplish what I need.

    Edit:
    I noticed that there is a Clipstate.Transition class that does something that I want but is there a way to include exit window depending on previous animation, or do I have to implement the exit times completely manually with events or something?

    Edit2:
    I also looked at the finite state machine examples. Is there any mechanism to specify transitions like in the vanilla animator? I could attach a bunch of different states on weapons and check in those states' CanEnterState() what state its coming in from and then adjust the transition based on that, but doing it from code would be quite tedious and I wouldn't get the preview of the transition like in mechanim visual editor
     
    Last edited: Jan 14, 2021
  34. Marsunpaisti

    Marsunpaisti

    Joined:
    May 3, 2018
    Posts:
    22
    Last edited: Jan 14, 2021
  35. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    There isn't currently any sort of standardised animation set system so you would need to implement it yourself. You wouldn't plug it into the Animator, you would simply reference it in your own scripts to do something like:
    Code (CSharp):
    1. var from = animancer.States.Current;
    2. var to = attackClip;
    3. var transition = transitionSet.Get(from, to);
    4. animancer.Play(transition);
    The transitionSet could store separate transitions for each combination or a single transition with some dummy events that it uses to set the end time before returning the transition.

    I posted some thoughts about How to implement transition sets a while ago, but haven't yet figured out how to solve the problems I mentioned there. Getting that system working would allow me to build a visualisation system to show the interconnected transitions and preview them like in an Animator Controller (without that system, it wouldn't really be possible because the relationships between states are entirely controlled by your code so the preview tool wouldn't be able to access them in a meaningful way). The current Preview system only previews a single transition without any particular relation to other states the character might have.
     
  36. Marsunpaisti

    Marsunpaisti

    Joined:
    May 3, 2018
    Posts:
    22

    Some sort of visual editor would be a nice thing to have since we are giving that up while moving to animancer from mechanim.
    For example in my use case I think I would ideally like to add a list of different AttackStates to my weapons, which could then in their CanEnterState() check against a list of allowed states/clips (not sure whichis smarter) from which it is allowed to enter the state. In addition to this for each list item I would have to specify the transition details like duration, offset, and exit time (or even better, an 'exit window'). Then the development experience would feel somewhat like mechanim without all the limitations.

    On the topic of the concept of having an "exit window": I noticed I'm often defining sections of my animations using events like "StartComboWindow" and "EndComboWindow". Having a mechanism that allows developer to 'label' a section of animation would be really nice. Currently using two events for this can lead into nasty bugs when animations get interrupted and the section end events get missed and then you end up in some unintended state.
    If implemented, these sections would be particularly useful for defining interruptable sections of animations (like attack windup), exit windows to other states, sections where a certain hitbox is enabled and so on.
     
    Last edited: Jan 15, 2021
  37. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    I doubt I'd ever seriously consider an exit window system (unless lots of people want it) because defining interruptible sections of animations makes no sense in Animancer where all animations are always interruptible. The Interrupt Management example explains a few ways to handle that sort of thing using the finite state machine system (not the animation system). Simply having your OnExitState method run the EndComboWindow logic would avoid getting stuck in an unintended state.

    Also, the Attack Input section in the Weapons example explains how you can set up an input buffer which gives the player much more consistency than having different exit windows for each animation.
     
  38. baumxyz

    baumxyz

    Joined:
    Mar 31, 2017
    Posts:
    107
    Hello, I bought Animancer Pro the other day.
    I've been trying to implement a state machine for my character all day. I have a character controller game object. This contains all the character logic and my state machine.

    Code (CSharp):
    1. public class VCharacterController : BaseCharacterController
    2. {
    3.     [SerializeField]
    4.     private AnimancerComponent _Animancer;
    5.     public AnimancerComponent Animancer => _Animancer;
    6.  
    7.     [SerializeField]
    8.     private VAnimState _Idle;
    9.     public VAnimState Idle => _Idle;
    10.  
    11.     public StateMachine<VAnimState> StateMachine { get; private set; }
    12.  
    13.     public Action ForceIdleState { get; private set; }
    14.  
    15.     public override void Awake()
    16.     {
    17.         ForceIdleState = () => StateMachine.ForceSetState(_Idle);
    18.         StateMachine = new StateMachine<VAnimState>(_Idle);
    19.  
    20.         base.Awake();
    21.     }
    22.  
    23.     public void TrySetState(VAnimState state) => StateMachine.TrySetState(state);
    24. }
    The child object is the character model. This object has the Animator, Animancer and a State component for the default state (idle).
    I have looked at the various examples, however I absolutely do not know where to now place the other states in my hierarchy. In the examples the events to change the state are sent via Actions using UI buttons. In my case, I would like to trigger the actions all in the character controller. But to which objects do I assign all the state components? (Walk, Run, Attack, etc.)
    I need the states to assign the animation clips in the inspector.

    Or am I misunderstanding something? I have strongly oriented myself on the Creatures Example.

    Code (CSharp):
    1. public class VAnimState : StateBehaviour
    2. {
    3.     [SerializeField] private VCharacterController _CharacterController;
    4.     [SerializeField] private AnimationClip _Animation;
    5.  
    6.     private void OnEnable()
    7.     {
    8.         var state = _CharacterController.Animancer.Play(_Animation, 0.25f);
    9.         if (!_Animation.isLooping)
    10.             state.Events.OnEnd = _CharacterController.ForceIdleState;
    11.     }
    12. }
     
  39. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Only the Creatures and Interrupt Management examples have the states on UI buttons. Brains and the later ones have the states on the character's objects, often on the same object as the script that uses them. So the Idle state is on the base Creature since the Creature script needs a reference to it and the Locomotion state is on the same object as the Brain because that's where it is used.

    If you have my Inspector Gadgets plugin, you could have all your states on a single object since it lets you choose which component you want when you drag and drop into an object field, but without it Unity just assigns the first matching component which isn't very helpful.

    You could even just have a separate object for each state. It would be rather wasteful, but unlikely to cause any real performance issues.
     
    baumxyz likes this.
  40. baumxyz

    baumxyz

    Joined:
    Mar 31, 2017
    Posts:
    107
    Thank you!
    Can I ask another short question?
    I have now created an attack state. I want the Idle state to be activated again after the attack combo is finished. The transition back to Idle works fine, however, I get the following messages in my console:
    "Possible Bug Detected: An End Event did not actually end the animation"

    AttackState:
    Code (CSharp):
    1. private void Update()
    2. {
    3.     if(CharacterController.isAttacking && CharacterController.isGrounded)
    4.     {
    5.         AnimancerState state = CharacterController.Animancer.Play(_AttackCombo, 0.15f);
    6.         state.Events.OnEnd = CharacterController.ForceIdleState;
    7.     }
    8. }
    Character Controller:
    Code (CSharp):
    1. public override void Awake()
    2. {
    3.     ForceIdleState = () =>
    4.     {
    5.         StateMachine.ForceSetState(_Idle);
    6.         isAttacking = false;
    7.         useRootMotion = false;
    8.     };
    9.  
    10.     StateMachine = new StateMachine<VAnimState>(_Idle);
    11.  
    12.     base.Awake();
    13. }
    How can I prevent this event from firing over and over again?
     
  41. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    As long as your Idle state plays an animation as soon as it's entered, you shouldn't be getting that warning.

    The warning explains how you can disable it, but I would first try some debugging to make sure it is actually entering that state correctly and playing an animation because there could be something else going wrong.
     
    baumxyz likes this.
  42. baumxyz

    baumxyz

    Joined:
    Mar 31, 2017
    Posts:
    107
    Thanks! I will have to take another look at it.

    I still have one quick question. I have now created a layer for the upper body. This layer is set to overwrite. I have only one animation on this layer. When I play this animation via Play(), there is no transition. As FadeIn time I have passed 0.5f. I guess it's because it can't fade between two animations from different layers. Is there a solution for this? Or what approach should I take for this use case?

    Thanks a lot for the really good support! I will give Animancer five stars today as I really like the asset and it takes an incredible amount of work off my plate. You just need to get an overview of all the features first.
     
  43. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    The Layers example doesn't have any issues with fading in an animation on a previously unused layer.

    What does your code look like?

    Also, if you have any suggestions for how I can more effectively introduce new users to the system please let me know.
     
    baumxyz likes this.
  44. baumxyz

    baumxyz

    Joined:
    Mar 31, 2017
    Posts:
    107
    EDIT: I found my error... I'm calling Play(...) every frame, so there is no time to show the transition. If I'm calling Play(...) once the transition is working. Sorry my bad!

    But I still don't know how to include my layered animation. "ShieldBlock" can be used on different states. Do you have a suggestion for this kind of use case?


    Original post:

    I have the following hierarchy:

    001.png

    ECM_Character is my character controller. It has the following components:

    002.png

    CharacterModel is my character mesh. It has the following components:

    003.png

    In the controller Awake() method I have the following code:

    Code (CSharp):
    1. Animancer.Layers[1].SetMask(_UpperBodyMask);
    2. Animancer.Layers[1].SetDebugName("UpperBody");
    Inside my HandleInput() method (inside the controller) I have the following (not final) code:

    Code (CSharp):
    1. if(_inputDevice.RightBumper.IsPressed)
    2. {
    3.     Animancer.Layers[1].Play(_ShieldBlock, 0.5f);
    4. }
    5. else
    6. {
    7.     Animancer.Layers[1].Stop();
    8. }
    So as long as the right bumper button is pressed I want to play the _ShieldBlock animation (on layer 1).

    I'm using a StateMachine but I don't know how to handle animations on different layers within the different states.

    The above code works BUT there is no transition.
     
    Last edited: Jan 22, 2021
  45. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    I can't see anything wrong there. Stop will cancel the animation immediately, but that Play call should make it fade in over 0.5 seconds.

    Check if any other scripts might be interfering with that layer and see if you can spot the problem if you look at the AnimancerComponent in the Inspector during the transition (maybe increase the duration or use the TimeScale component to slow it down to in case something is happening really quickly).

    Otherwise, if you email a minimal reproduction project to animancer@kybernetik.com.au I'd be happy to take a look at it for you.
     
    baumxyz likes this.
  46. neo-mashiro

    neo-mashiro

    Joined:
    Aug 7, 2020
    Posts:
    19
    Hello, I'm following the "uneven ground" IK example and would like to extend it to a mixer state of walk and run animations. For a single clip, I know I can use IK curves to find the weight in each frame, but a mixer is a blend between animations, how should I get the right weight?

    I'm thinking about setting the IK weights in code based on the y position of the foot, that way I can work with any transitions without defining an IK curve. While this is possible, I just wonder if there's a better approach with Animancer, for example, accessing the blending values of two IK curves.

    Sorry for bothering you with a question unrelated to Animancer. I'm new to Unity and would love to hear your advice. Thank you very much!
     
  47. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    The system for accessing animated properties already blends the values of all states according to their weight so as long as the clip for each state in your mixer has an appropriate curve you'll be able to access the blended value based on the mixer's current parameter.
     
    neo-mashiro likes this.
  48. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    Hiya! Hey just wondering, is there a way to blend with a mask if you are using a generic rig?
    Thanks,
    P.
     
  49. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    Layer Masks have a Transform section for Generic Rigs below the Humanoid section.
     
  50. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,817
    Oh cool! Thanks for that. :)