Search Unity

How to keep the highest Y between the base layer and its overriding layer ?

Discussion in 'Animation' started by manutoo, Mar 23, 2019.

  1. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    524
    Hello,

    I have a tennis player running and striking the ball at the same time. I have a run animation and a strike animation. If he doesn't run, only the strike animation applies. If he runs, I use a 2nd layer applied only on the legs & pelvis which plays the run animation.

    Here's my problem : the strike animation can be "jumpy", and in such case, I'd like the player to still jump even if he's running, so it'd look better. But if he's bending the knees in the strike animation and thus get lowers, it shouldn't affect his final height, else it'd look very strange.

    It's working like that in my non-Unity engine, and I'm checking & changing the Y on the Pelvis bone.

    Is there a way to do a script that would get the current pelvis Y of both animations and applies the highest one ?

    Notes:
    - I don't use root motion ; if only a root motion solution would work here, I'd have to also find a way to turn it on only for that
    - I'm currently using Unity 5.6, but eventually I'll switch to Unity 2019, so if you have a solution working only on the later, it'd be better than nothing :)
    - I need to do that in realtime, so I can't use the editor only API
    - I guess I could achieve that using AnimationClip.SampleAnimation() , but it seems rather overkill
    - the only solution I see is to use a hidden duplicated player on whose I play only the current strike animation, in sync with the visible player, and compare the resulting height between the 2, which is still not great performance wise, plus it's cumbersome to implement


    Thanks in advance for any help !
     
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    This sounds like something the Animation Jobs system introduced in 2018.2 would be able to do, but I don't have any experience with it.

    A hacky workaround that might work is if you get the pelvis Y position curves from each of the animations in the editor and serialize them in your script (because getting a curve is editor-only functionality for some reason), you could sample those curves at the current animation time instead of needing to sample the entire animation.

    Or if you're using a generic rig it might be possible to use your duplicate player idea, but only give the duplicate a pelvis bone so that it doesn't waste performance on all the other bones you don't care about.
     
    manutoo likes this.
  3. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    524
    @SilentSin,
    thanks for the head up : indeed the new animation job has been designed exactly for this kind of issue ; there's even a sample in the introductionary blog post here => https://blogs.unity3d.com/2018/08/27/animation-c-jobs/ . It's still experimenal though. Hopefully, it'll be fully working sometimes during the 2019 cycle.

    Meanwhile, I think I'm going to take the route of having a duplicated player, but with a little change : it'll act as my 2nd layer, so I won't have a 2nd layer in my visible player state machine, and I won't have to worry about maintening the sync between the invisible player and the visible 2nd layer.

    And then I'll manually blend the 2 animations together, stiching the pelvis values exactly to my liking, which should be performance-wise relatively close of having the 2 animations within 2 layers of the same state machine, especially with your tip about keeping only the bones needing the separate animation (ie: the upper body part + the pelvis). :)