Search Unity

Problem with root motion - Animation not playing correctly and not transitioning properly

Discussion in 'Animation' started by JanDawid, Oct 9, 2015.

  1. JanDawid

    JanDawid

    Joined:
    Jul 7, 2014
    Posts:
    283
    So basically, I have a character that moves around without root motion most of the time, however when it comes to climbing ledges I turn on root motion and let the animation move the character up the ledge. This works well in every area apart from one and I have no idea why:
    If the character is moving slowly off a ledge, an animation plays where the character holds the ledge beneath and drops down while holding onto the ledge and ends up dangling from it (so walking (no root motion) > grab-beneath animation (root motion) > grabbing state (no root motion)).
    The grab beneath animation does not play as intended as the character just sits in place and the animation plays out in the same spot. After that, when transitioning into the grabbing state animation, the model moves upwards suddenly (the capsule collider that is the character stays in place and the model shoots up slightly out of the center). When entering the grabbing state in an alternate method (grabbing on in mid air) the character does not do this, it's only happening when transitioning FROM the grab-beneath animation.
    The grab-beneath animation works NO DIFFERENTLY from the animations where the character climbs up ledges (walk (no root motion) > climb ledge animation (root motion) > walk (no root motion)) which work exactly as intended and essentially use the same code. I know there's nothing in my scripts affecting this so it's purely based on the animations and their settings.

    The model is rigged as a Humanoid (otherwise the root motion movement doesn't work), the animations where root motion is applied are not set to loop while the ones it transitions to and from are... Not sure what else I can explain. Is there any way to just have my animations play like I made them to? Root motion seems to be messing with them but I have no idea how else to program these actions (I tried before where I would set the collider to go to where the model is (had the model as a child object to a capsule collider) however this would cause an unavoidable flicker as there's no way to have the collider go to the position of the model without moving the model further along as the model is a set distance away from the collider).

    So, why isn't the animation playing out like it should? And why is the origin of the model changing after this particular transition?
     
  2. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    That's an odd setup so I'm not surprised of the results you are getting.
    Did the animation work as intended when initially setting up the controller and mecanim states, or did you have to fudge a lot of stuff to get it to work properly?
    In order to answer your last question - since it seems a little complicated to me - I'd have to have hands on the project, which I don't think you probably want, and I really don't want either. :)
    My semi-educated guess is I think all the animations should have root motion or all shouldn't. Mecanim offers to remove or add root motion so I think that should be done.
    Another more experienced dev may have a better solution, but my suggestion is to add root motion to all the animations that don't have it by this method. Though you may decide to remove root motion from the small number of animations that have it instead. I'd choose the former since I don't think code should drive the locomotion of any character -
     
    JanDawid likes this.
  3. JanDawid

    JanDawid

    Joined:
    Jul 7, 2014
    Posts:
    283
    It is an odd setup, but it's been working for the animations and it's just weird that it's not working for this particular one.
    The other animations worked fine when I set it to use root motion while they played and then turned it off after; I should mention I'm importing the model and animations from Blender as a .fbx file.
    Yeah I can't really explain too much without handing the project over to someone to look at it when it's a little complex at this point. I could probably just pay someone £10 to look at it and give me a solution, lol.
    I guess I'm going to have to go all in or all out then so... I'll weigh my options. The code-controlled character has been working flawless for me so it's not exactly at a disadvantage because of it (apart from the ledge climbing animations which really need the animations' movements to make it look realistic).
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Jakeiiii: Hi, if I may ask:

    1. What is your setup hierarchy like? (root, then character+collider under it or something else?).

    2. Are you moving Rigidbody or Transform?

    3. Are you by default moving either of above, and then using ApplyBuiltInRootMotion?

    4.Do you disable your collider (if you have one) while moving using root motion?

    5. Do you have active forces like drag, friction and such while executing this movement?

    I'm just guessing, have been testing similar in a side project of mine.
     
    JanDawid and theANMATOR2b like this.
  5. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Yeah Jake - I meant no disrespect by my opinion about code-controlled characters. I believe it's either/or and both options work as needed depending upon the game and the developers taste. It just so happens I'm an animator - so I like to keep the motion of the character in my own wheel house. :)
    It's worth stating most, if not all characters pre-ps2 era were code-driven. ;)

    Please update this thread when you figure the solution. I'm interested in knowing what the actual problem happens to be and the solution you end up with.
     
    JanDawid likes this.
  6. JanDawid

    JanDawid

    Joined:
    Jul 7, 2014
    Posts:
    283
    Hi everyone; it just seemed that the problem was because I was mixing the two and it really should just be either/or. I've decided to just carry on with my old method of it being code driven, which still leaves me with the issue of the ledge-climbing animations: I have the collider stay in place while the animation plays (moves away from the character) and when the animation reaches the final position I set the collider to go to the models position; and so at times this causes a flicker in the characters appearance and I was wondering if there's a smoother way to do this that doesn't use root motion?

    And out of curiosity....
    1. The top is the parent object you get in an .fbx file, which has the animator, collider and scripts attached, then the armature and meshes, then the root bone, and so on.
    2. Rigidbody.
    3. I turned off all the movement in the code during those animations (including any ambient forces like gravity (my own custom gravity)).
    4. I disabled the layer collisions during the animations as having them on, the character would get stuck on the ledges.
    5. No other active forces; any forces are purely through code and I disabled those.
     
  7. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Jakeiiii: so the setup is quite similar to what I ended up with. Now that I checked my setup, I actually avoided similar issues by not having offset in any other axis than Y when jumping up then transitioning to idle. I don't have climb down to hanging animation available so I can't replicate your setup.

    What you could check (I bet you know more about mecanim than me, based on seeing your videos, but anyway):

    1. Check animator.pivotPosition. According to unity it's "the most stable point between feet". It moves during animation clip playback, and if you unfold animator component, you'll see it's blue gizmo.

    2. Check the Root Transform Position (Y) + and (XZ) too. Try setting both as Baked into Pose + Original. What this seems to mean (trial and error here...) is that root of this clip is not moved at all during playback of this animation clip.
    This seems to be only setting making sense for animations that should be placed into world exactly, animated move across box platform and such, I think this can be thought as animation moving relative to 0,0,0 of Maya/Max/Blender world origin. This also negates the use Root Motion of Animator, with this setting it doesn't matter as clip settings itself already do this.

    3. I did use the same settings for hanging and idle - Root Transform Rotation, Root Transform Position (Y) and Root Transform Position (XZ) too all are set as Bake into Pose + Original. With this I eliminated Unity from trying to add some calculated offsets during animation playback, making it hard to see what happens with translations.

    4. Check how rb moves during climb animation; as you know already I guess, it stays put in position defined by first frame of climb, at least with these above mentioned clip settings.
    There seems to be some funny stuff happening - when animation of climb reaches 1, it already snaps to first frame, i.e. back to where it was during climb first frame / where rb stays. And now if animator transitions to idle, idle starts animating at position of 1st frame of climb.... I think this is a feature I don't like - feels more like a bug?
    To counter this, try following; store pivotPosition all the time. When nearing very end of animation clip, transform object, but NOT by using rb.MovePosition or rb.position - use transform.position instead. Set object to last pivotPosition.
    For this I used 0 length transition for climb-idle - otherwise if I observed correctly, climb animation tries to transition to idle so that idle animation root position blends from current climb position towards location of rb. Not good.
    By using 0 length transition + offset transform at end results into small "snap". As I move rb to pivotPosition, even if climb last frame and idle first frame are the same, there will be slight offset, and in addition to this pivot seems to wobble like crazy occasionally.

    So that's all I can think, I don't know the system yet so well, maybe someone more informed might help? And I'd have to check all the mecanim tutorials, I guess there might be something related to this, don't remember.

    Then there is MatchTarget, but last time I tested it I couldn't get it working, maybe there is a tutorial about this? Didn't find anything with quick search.

    I'm not sure if this is going to help at all :) but anyway, to me it feels like there could be similar event going only in reverse direction.
     
    theANMATOR2b likes this.
  8. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    JanDawid likes this.
  9. JanDawid

    JanDawid

    Joined:
    Jul 7, 2014
    Posts:
    283
    @eses
    So my set up basically works like point number 4. What I do is that when the animation starts playing (animation bool gets set to true) I start a co-routine and during this time, the rigidbody is kinematic and will not move. I yield a new WaitForSeconds in the co-routine and have the animation play until x-seconds are up (when the animation has reached its end position). The animations stays at this position so it doesn't finish JUST as it gets to the end position, so it keeps playing at that end position for another second or so. When the seconds are up: the collider is moved (via transform.position) to the models position, the bool is set to false so that it transitions to the idle state, and the transition time is zero (dead-on zero).
    This still has the flicker happen on occasion. Either Unity is lying when it says that a zero-seconds transition is instant or I'm still doing something wrong. Because if this all happens in the same frame with no transition time, why am I seeing a transition?
     
  10. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Another variant.

    Got a little bit of help. And really have to re-check all of those mecanim videos, I think I've forgotten too many small things, and info is all over the place IMHO.

    Root Transform climb to idle 2: https://db.tt/21Aq2Jme

    I think I have to make a proper write-up, otherwise I'll forget it before too long. Main point is that I added separate null object for climb clip.

    Then I assign this null object (create in 3d soft) as source of root motion.

    It just sits in 0,0,0 and when character has moved on platform, nearing standing up pose, I move it between feet - you can see the animation path from capsule in video.

    Idle clip and edge hanging clip both have Original+Bake so they basically have animation relatively to their 3d scene origin.

    Climb clip does not, as these options are missing when setup uses external root motion source object.

    DoF setting was checked in Configuration of avatar, don't know why but Importer was complaining about it yet it didn't make any difference.

    While animating, I switch kinematic on all the time for animation driven movement +/ gravity off. Root motion was on whole time as there not that much going on.

    It makes things better in two ways:
    + No need for moving character at the end of climb
    + Can have blend between climb and idle

    Negatives

    - Not that many, have to fiddle with extra object but it's only needed in problem clip
    - Seems there might be some issues if external root object is moved too fast, maybe there is some back transform stuff in mecanim going on? If I moved null too fast, there was a dip in character movement at that point.

    No idea if this is the way to go to but so far it works, but I don't think I've got much more time to test this right now.
     
    theANMATOR2b likes this.
  11. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Jakeiiii: answer to your reply - I'm not quite sure about that flicker - with first setup I get it when moving rb.Moveposition (FixedUpdate?) and rb.position (does it happen in FixedUpdate too?) but I didn't see it when moving character using transform.translate in Update like I mentioned above.

    Edit: To me it seems that at last frame of clip (when stepping frame at time) animation clip already moved root of skeleton back to it's first frame position? Not quite sure if I observed this correctly, but seems wrong IMO.
     
  12. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Hey eses - great to see you troubleshooting this. What is the parent of the null you used in the 3D app? Is the null parented to the root? or is the root parented to the null, or is it not parented to anything?
    Looking ahead I'm just seeing some complications - if retargeting is desired - if this null is part of the hierarchy.

    Nice work.
     
  13. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    theANMATOR2b: I just tossed it under root of character = both skeleton hip and this extra root node are under root object in 3d soft. I've got no idea if this will work with all the things I need - yet.
     
    theANMATOR2b likes this.
  14. holliebuckets

    holliebuckets

    Moderator

    Joined:
    Oct 23, 2014
    Posts:
    496
    Has anyone submitted a bug report yet, and could you please post it for me? Thank you!
     
  15. pha

    pha

    Joined:
    Oct 23, 2012
    Posts:
    20
    I have with same problem with my climbing animation where the Collider just sits on the ground and not following the player. When I do a normal jump I can see the Collider move up the air with player, but not when is climbing. It seems to me that the distance doesn't get checked during the climbing animation therefore the player transform.position stay at zero in the Y direction, and that's why the collider just sit there.
     
  16. holliebuckets

    holliebuckets

    Moderator

    Joined:
    Oct 23, 2014
    Posts:
    496
    If you have not submitted a bug report I would be so thankful if you would, and could you please post the Bug # for me :D Let's get this fixed