Search Unity

Animancer - Less Animator Controller, More Animator Control

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

  1. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    The mixer transition already has a Fade Duration field so you don't need to have a separate
    transitionTime
    unless you want to override it. Other than that, your code looks fine. Is there some reason you think you're not doing it right?

    Are you using the latest version of Animancer (v4.4)? Because the URP issue should be fixed in it. Otherwise could you please let me know which version of Unity and the URP package you are using so I can take a look at it.
     
  2. Deleted User

    Deleted User

    Guest

    Well, i still didn't quite understand when to use Mixers / States, sorry it's a bit confusing for me.

    I want to have a set of animations when the character is onGround (idle, walk, run, sprint etc) and a set when he's in the air (startJump, middleJump, endJump) and also be able to interrupt those with like wallClimb (when OnGround) or ledgeGrab (when midAir).

    What's the best way you'd suggest implementing it ? Can you pinpoint me to a starting direction ?

    Regarding materials; using latest version, and i just pulled it back right now to make sure, same think. Preview is pink. Using 2019.3.6f1 (URP 7.3.1)
     
  3. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    The Airborne page in the 3D Game Kit example explains how you can use a mixer to blend the jump pose based on the character's vertical speed. Or if you just want to play the start/middle/end one after the other, the Sequence Coroutine example shows a simple way of doing that.

    Interruptions are entirely up to you. Your scripts can tell Animancer to play whatever you want and it will do so.
     
  4. Deleted User

    Deleted User

    Guest

    Ok will try cloning the 3D GameKit demo. Thanks !
     
  5. Deleted User

    Deleted User

    Guest

    I think i've found a bug (but hopefully it's just me). In the 3d Game Kit demo; when I try to add a random animation in the IdleState i get this error (removing animation works) :

    Code (CSharp):
    1.  
    2. NullReferenceException: Object reference not set to an instance of an object
    3. Animancer.Editor.TransitionDrawer+TransitionContext.Get (Animancer.Editor.TransitionDrawer drawer, UnityEditor.SerializedProperty transitionProperty) (at Assets/Plugins/Animancer/Internal/Editor Utilities/Inspector/TransitionDrawer.cs:424)
    4. Animancer.Editor.TransitionDrawer.OnGUI (UnityEngine.Rect area, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Assets/Plugins/Animancer/Internal/Editor Utilities/Inspector/TransitionDrawer.cs:102)
    5. UnityEditor.PropertyDrawer.OnGUISafe (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at /Users/builduser/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyDrawer.cs:23)
    6. UnityEditor.PropertyHandler.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.Rect visibleArea) (at /Users/builduser/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:139)
    7. UnityEditor.GenericInspector.OnOptimizedInspectorGUI (UnityEngine.Rect contentRect) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/GenericInspector.cs:104)
    8. UnityEditor.UIElements.InspectorElement+<>c__DisplayClass55_0.<CreateIMGUIInspectorFromEditor>b__0 () (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/InspectorElement.cs:515)
    9. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at /Users/builduser/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:187)
    10.  
     
  6. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    That sounds very similar to this issue, so try the fix I posted there (just use Ctrl+F to find
    Instance.MaximumDuration = Instance.Transition.MaximumDuration
    in the solution). Let me know if that works.
     
  7. Deleted User

    Deleted User

    Guest

    Yes that was it ! Thanks !

    While there, I couldn't find a way to add fade animation individually in a MixerTransition; is it even possible ? Or is it the treshold that makes the animation 'fade' in/out ?

    Capture d’écran 2020-04-13 à 17.44.24.png
     
  8. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Fade Duration is the top field in your screenshot. If you call Play(transition) it will fade using that duration so you don't need to have your own
    transitionTime
    field separately.
     
  9. Nosaru

    Nosaru

    Joined:
    Feb 26, 2017
    Posts:
    13
    Is there a way to set speed of animations for the Animancer component, not a singular clip like mentioned in the faq?
    I need to freeze all animations on all objects during TimeStop events...
     
  10. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
    I'm trying to partially blend a layer, but I don't want the full weight of the layer. Is there a way to play an animation with a target weight of 0.4, ie which isn't 1. Start at 0 weight and blend the layer in to a target weight of 0.4.

    Will this be sufficient, as I'm not convinced this is doing what I want it to.
    Code (CSharp):
    1. Creature.Animancer.Layers[Creature.BlendingLayer].Play(drawAxeUnderArmAnim1, 0.25f);
    2. Creature.Animancer.Layers[Creature.BlendingLayer].StartFade(0.4f, 0.25f);
     
    Last edited: Apr 22, 2020
  11. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    @Nosaru If you want to set the speed for everything you can use
    animancer.Playable.Speed = ...
    but if you want to pause everything then
    animancer.Playable.PauseGraph()
    is even more efficient.

    @craigjwhitmore Use Debug.Break to pause the editor when you start the fade so you can see what weights and targets it ends up setting in the Inspector. The Play method does do some stuff with the layer's weight which might be interfering with what you want, in which case you could just make a copy of it as an extension method with that part removed. Let me know what you end up doing because I'm not totally sure how it should be implemented myself.
     
  12. Nosaru

    Nosaru

    Joined:
    Feb 26, 2017
    Posts:
    13
    Hey, thx! Dunno how I missed that xD
     
  13. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
    I'm not really sure it's doing the correct thing. The weight seems to remain at 1 until it changes to the next state at which point it goes straight to 0.

    In any case, I've scrapped what I was doing with this idea as it just wasn't working out, regardless of the Fade.
     
  14. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    That doesn't sound right. Do you still have a copy of your script so I can try to track down the issue?
     
  15. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
    I've spent some time looking at what I was trying to accomplish and made some progress. I had an event that was causing it to change state before it could execute the fade. So doesn't seem to be an Animancer issue after all. I've checked the fades and they all seem to be working ok.
     
  16. launzone

    launzone

    Joined:
    Dec 2, 2015
    Posts:
    57
    how do i set the weights of states?
     
  17. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    launzone likes this.
  18. mutp

    mutp

    Joined:
    Oct 1, 2018
    Posts:
    79
    Hi, I was wondering how I could change the AnimationClip associated with an AnimancerState at runtime?

    My specific use case is this -
    I want to change the jump clip at index 1 depending on certain conditions.

    I do this on awake

    Code (CSharp):
    1.  
    2.     [SerializeField] private AnimationClip start;
    3.     [SerializeField] private AnimationClip left;
    4.     [SerializeField] private AnimationClip front;
    5.     [SerializeField] private AnimationClip right;
    6.     private LinearMixerState jumpMixer;
    7.  
    8.     private void Awake()
    9.     {
    10.         // Make a new mixer and connect it to the default layer.
    11.         jumpMixer = new LinearMixerState();
    12.  
    13.         // We could specify custom thresholds in the Initialise call,
    14.         // but since we are not it will use 0 and 1 respectively.
    15.         // Other overloads take 3 clips, or an array of any number of clips.
    16.         jumpMixer.Initialise(start, front, -7, 8.5f);
    17.        
    18.         // Optionally disable Synchronisation for states that do not need it.
    19.         // In general, synchronisation is good for movement so you should disable it for Idle
    20.         // and since there is only one other state it will have nothing else to sync with anyway.
    21.         jumpMixer.SynchroniseChildren = new bool[] { true, true };
    22.     }
    23.     /************************************************************************************************************************/
    24.  
    25.     public void PlaySequence()
    26.     {
    27.         // Play the mixer just like a regular clip.
    28.         AnimationClip anim = IsLeft ? left : right;
    29.  
    30.         AnimancerState state = jumpMixer.GetChild(1);
    31.         state.Clip = anim;
    32.         Runner.Animancer.Play(jumpMixer, 0.25f, FadeMode.FixedDuration);
    33.     }
    34.  
    It doesn't switch the clip and throws an error the first time if I trigger a left/right animation the first time.
    The error - "AnimancerNode.Root is null when attempting to create its Playable: "
     
  19. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
    @mutp Wouldn't an easier solution be to have 2 Linear mixers, one for left and one for right and choose which one to play depending on the state of IsLeft?

    However, if you are really adamant that you want to, you can do the following. I've changed some values as your values weren't clear to me what you were intending.
    The key point is that you need to initialize 3 states in Awake, then modify it during run time.

    Code (CSharp):
    1. private void Awake()
    2.     {
    3.         jumpMixer = new LinearMixerState();
    4.  
    5.         jumpMixer.Initialise(3);
    6.         jumpMixer.CreateState(0, start, 0);
    7.         jumpMixer.CreateState(1, right, 4);
    8.         jumpMixer.CreateState(2, front, 7);
    9.  
    10.         jumpMixer.SynchroniseChildren = new bool[] { true, true };
    11.     }
    12. public void PlaySequence()
    13.     {
    14.         // Play the mixer just like a regular clip.
    15.         var anim = IsLeft ? left : right;
    16.         var child = jumpMixer.GetChild(1);
    17.         child.Clip = anim;
    18.  
    19.         Animancer.Play(jumpMixer, 0.25f, FadeMode.FixedDuration);
    20.     }
    Having 2 mixers in some circumstances might be more flexible, as you can then blend between the 2 mixers by setting their respective weights or even nest them and use a parent mixer to blend between the two child mixers. Food for thought for you.
     
    Last edited: May 1, 2020
  20. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    @mutp The
    AnimancerNode.Root
    only gets set when you first Play the state, so setting the clip after that should avoid that error.

    I would probably just use multiple mixers as @craigjwhitmore suggested because changing the clip will need to destroy and recreate a playable so it will take more processing time where having more mixers would be faster at the cost of more RAM usage (and RAM is rarely a bottleneck nowadays).
     
  21. mutp

    mutp

    Joined:
    Oct 1, 2018
    Posts:
    79
  22. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    704
    Hi, I have one question regarding the hybrid method.
    I'm using 3rd-party character controller that uses unity Animator.
    Will Animancer Hybrid Component will work with the exiting Animator?
    A quick test shows that I cannot mix Unity Animator API with Animancer.
    For example, Animator.CrossFadeInFixedTime(), will not do anything when mixed with HybridAnimancerComponent.
    Is this an expected behavior? or a bug?

    Thanks.
     
  23. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    I upgraded a Unity 2019.3.11 project with Animancer Lite 4.4 to 2019.3.12. Now when I bring any source files that use AnimancerComponent into Visual Studio it complains that 'the type or namespace AnimancerComponent cannot be found'. It does this on the example files that come with Animancer as well. The files do include 'using Animancer'.

    But the project will still compile from Unity if I make a change in VS with it showing the errors. I have Playmaker installed and VS can still see it, it just seems to not be able to see Animancer.

    I tried uninstalling/reimporting Animancer but same problem.
     
  24. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    @chrisk That's correct, the HybridAnimancerComponent (and its Controller property) have their own methods which you need to use instead of the regular Animator methods.

    @kphipps That can't really be an Animancer problem if Unity can compile it properly. There must be something your IDE has not refreshed. Are you using the latest version of Visual Studio with the Unity Tools installed?
     
  25. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    704
    Hmm.. I see. Is there a way you can make it co-exist with Animator? It will be rather difficult to modify a 3rd-party controller, and cumbersome to patch it every time there is an update.
    Thanks.
     
  26. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Unfortunately not, those methods can't be used with the Playables API so you would need to make that feature request to Unity.
     
  27. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    I'm using:

    Visual Studio Community 2019 16.5.4
    Visual Studio 2019 Tools for Unity 4.5.1.0

    I found that VS suggests changing AnimancerComponent to IAnimancerComponent (for some reason it can only see it).

    I agree it seems to be a VS problem, but it works with Unity 2019.3.11, and VS only has the problem with Animancer and Unity 2019.3.12 as far as I can tell. Maybe it's a VS or Unity Tools Issue, but Playmaker (which is the only other addon I'm using) works and VS can see it and also all the Unity stuff.

    I also found that VS doesn't have the problem if run with Unity closed. So 2019.3.12 seems to be doing something that's preventing VS from seeing Animancer.

    I tried uninstalling/reinstalling VS Tools for Unity, but the problem persists.

    Is there anything else could I do to force a refresh?
     
    Last edited: May 4, 2020
  28. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    That makes it sound like a compatibility issue between VS Tools and Unity 2019.3.12. Deleting all the files in the root of your project (outside the Assets folder) and the .vs folder might force a refresh but it's been a very long time since I've had to deal with an issue like that.

    Edit: changing the settings of the Assembly Definition file in Animancer then changing them back might also be worth trying.
     
  29. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    I tried both suggestions but no change. I'm assuming no one else is having this issue, so I will wait for the next Unity and Visual Studio updates and try then, and maybe try doing a clean install of VS.
     
  30. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    @Kybernetik
    Hi, this may not be Animancer related, but hopefully, you can help.

    I want my humanoid rig, to move into a particular state (lets call it "hi five"). My issue is that, I am not an animator. I have molded the rig into this state, by hand, so I have it on a model, frozen in this "hi five" position.

    What I am wondering is, can you recommend how I translate this, into the end frame of an animation Clip, so that I can apply that to Animancer? Or will I need to go into an animation program?

    Thanks
     
  31. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    I'm not an animator either so I'm pretty clueless about everything that happens before Animancer gets an Animation Clip but the general consensus seems to be that Unity's animation editing tools aren't great so using a proper modelling/animation program like Blender is generally better.
     
    renman3000 likes this.
  32. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Thanks..... uhg
     
  33. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
  34. zedz

    zedz

    Joined:
    Aug 31, 2013
    Posts:
    250
    One thing I dont understand is how to have complete separation between parts of the body, like with layer/masks
    eg the example 7 with the person idle/running and swinging the tennis racket

    1. idle legs/torso = idle
    2. walk legs/torso = idle
    3. press swing bat legs = walk / torso = swinging bat

    this works good
    but

    1. idle legs/torso = idle
    2. press swing bat legs = idle / torso = swinging bat
    3. change to walking whilst swinging bat, both legs & torso change to walking, i.e. the swinging animation is cut short

    what I do which seems very hacky is

    do the 1-3 above but then, remember where the torso swing was and fastforward the torso layer to this point

    float t = torsoState.Time;
    torsoState = animancer.Layers[TorsoLayer].Play( playing_torsoClip, transition_speed, FadeMode.FromStart );
    torsoState.Time = t;
    torsoState.Events.OnEnd = () => TorsoAnimationFinished( wantRunning );

    it sorta usually works but surely this is not how to do it
     
  35. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    In your second step 3 to change to walking if you are calling
    animancer.Layers[LegsLayer].Play(walk)
    then the TorsoLayer should not be affected and should continue the swing as is. Is that what your code looks like or are you doing something different?

    If you want to post a lot of code it will probably be easier to manage as a Github Issue.
     
  36. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    I am thinking about switching to Animancer over plan old Mecanim.

    Does Animancer support something like https://docs.unity3d.com/ScriptReference/Animator.MatchTarget.html?

    For the game I am working on, I will need characters to perform animations like sitting on chairs and benches with arbitrary locator points. I will want to use target matching to make sure the character is properly positioned at the the locator point.
     
  37. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Unfortunately target matching doesn't work with the Playables API. But from my understanding, target matching is essentially just a system for managing IK weights over time so it should be possible to achieve what you want using the technique described in the Uneven Ground example (or by just scripting the weighs yourself).
     
    Airship likes this.
  38. zedz

    zedz

    Joined:
    Aug 31, 2013
    Posts:
    250
    Mate In theory thats what should happen but its not working for me
    Have you tried your example 7 to to have true independence between the layers (person can change to walk/run, hit ball when ever they want in any order)
    I just can not get it to work
    the only way is the hack I posted above.

    I have been working on this for months, it was the main reason I switched to animancer
    It was one of the first questions I asked about it
    https://forum.unity.com/threads/ani...e-animator-control.566452/page-5#post-5302584

    I have been doing this so long that I cant think clearly about it any more.
    Are you sure its really possible to have true independence between the layers in a simple method?
    I just can not get it to work, its driving me nuts

    cheers zed
     
  39. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    The Layers example does not have truly independent layers because it moves the swing animation between layers (base layer while idle and upper body layer while moving). But layers on their own are independent as long as you aren't doing that.

    If you want to email me a simple scene and script to demonstrate the issue you're having with commands on one layer affecting the other, I'll take a look and figure out what's going on with it.

    Also, make sure you are updated to the latest version (4.4) because there were some issues relating to layers in the earlier 4.x versions.
     
  40. craigjwhitmore

    craigjwhitmore

    Joined:
    Apr 15, 2018
    Posts:
    135
    @zedz I made a 2d mixer for a full body walk/run animations base layer with a second layer for upper body that plays an equip/unequip animation. The Equip/Unequip can be played at any time. Is this the sort of thing you are trying to do?
     
  41. zedz

    zedz

    Joined:
    Aug 31, 2013
    Posts:
    250
    Yes mate sounds similar to what I need, Are you sure its solid? i.e. works in all occasions, have you stress tested it
    eg
    idle -> starts equiping -> starts walking (torso equiping animation carries on then fades to walking) .....
    walking -> starts equiping -> stops walking (torso equiping animation carries on then fades to idle) .....

    I just can not get it working in all cases.

    I've been programming over 30 years and this has stumped me more than anything since doing my own physics engine (this was a time before Havok, ODE, Newton etc) but that actually was hard, this should not be that difficult :D
     
  42. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hey, just wondering is there a way to control the 'Aim' controllers for the limb IK in Animancer? There are just a few points where I'd like to have a bit more control of where the character's elbows and knees are pointing.
    Thanks!
     
  43. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
  44. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
  45. SenseEater

    SenseEater

    Joined:
    Nov 28, 2014
    Posts:
    84
    upload_2020-5-11_19-58-54.png


    Unity 2019.3 | Latest AnimancerPro from store.
    ClipState.Transition throwing errors when initializing field/array
     
  46. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    That issue can be fixed with a couple of simple changes which I've described here.
     
  47. SenseEater

    SenseEater

    Joined:
    Nov 28, 2014
    Posts:
    84
    Thanks , that worked!
     
  48. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hi, just wondering, is there something like the end event that could happen a little earlier? I'd like to start transitioning back to my idle before the end of the last animation to get a nice crossfade. This is something I could probably write my own code for but I thought I'd check I wasn't missing something.
    Thanks!
     
  49. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    The End Events page shows how you can set the event time in code and the Golf Events example shows how you can set it in the Inspector when using Transitions.
     
  50. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Oh cool! Thanks.