Search Unity

Hitbox collider offset problem in imported root motion animation

Discussion in 'Animation' started by raybarrera, Jul 28, 2017.

  1. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    I have a bit of an issue trying to get a hitbox to work with my animation.

    Here's my setup:
    • I have an imported root motion animation
    • I duplicated the animation so that I could edit it in the animation tool in unity
    • I added a child game object to the character with a 2d collider on it (this is my hitbox)
    • I animated the collider to coincide with the punch animation
    • Because the animation for the collider is in the same clip as the mesh animation, it's on the same animation controller (in case that's not obvious).
    This looks fine in the preview when I scrub the animation or play it in the animation window, but there's an offset when I test in playmode.
    This is the animation when I set it up in the animation window. Looks fine.
    example1.PNG

    Same animation when I test it in play mode:
    example2.PNG
    I chose this workflow because it allows the designer to easily tweak hit frames, etc, and you can preview it easily. Having to animate the hitbox on a separate clip/controller would be a nightmare to line up.

    So, is there a way to fix this, and/or a better workflow to animate the collider?

    EDIT: This behaviour was observed in 5.6.0, 5.6.1 and 2017.1

    Thanks!
     
    Last edited: Jul 28, 2017
  2. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    Humanoid or Generic rig?
     
  3. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    It's a humanoid rig.

    I should also add, in case it's not clear from the post, that the character itself animates wonderfully with root motion.
     
  4. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    I'm not sure why it's happening, but what about making the collider object part of the character asset itself, eg. 2d plane standins for the hitboxes? Then you could animate the hitboxes along with the rest of the animation. In Unity you'd hide the plane's renderer and add a matching collider. This could also make later changes easier, since you wouldn't be duping the imported animation.
     
  5. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    We've definitely considered this option--that said, I'd much prefer if the designer had the ability to do the tweaks in Unity rather than having to do them in Maya/Max. I'm thinking it's a good fallback to an in-editor workflow, but I'm hoping there's a simple fix to my current issue.

    Either way, thanks for the feedback!
     
  6. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    What happens on the next animation cycle? Does the hit box move as desired but delayed?
    A video or gif of both preview and in play mode would be helpful - showing more than one animation playing sequentially with the results of the hit boxes showing.
     
  7. raybarrera-aofl

    raybarrera-aofl

    Joined:
    Sep 4, 2016
    Posts:
    7
    I'll do a gif later tonight and post. That's a great idea.

    The offset is always the same. I can trigger the punch animation from any location, move the character, do it again, and the offset is still wrong (but the same relative distance).
     
  8. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
  9. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    That looks like a double transform. I don't know if that happens in Unity, but it's common in other systems. The collider shares the animation clip and animation controller, but is it a separate asset with its own Animator? It could be getting moved by the motion of the character you parented it inside, then moved again by the hitbox animation. If so, you might try making the GameObject the collider lives in exist in the character asset, iand adding the collider to that (so there's only one Animator), instead of parenting a new object inside the character.
     
  10. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    It actually is on one animator. The character animation also drives the collider animation.
     
  11. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    Can you do a simple test - parent a non-animated hit box just like you did with the existing hit box and see what the results are?
    I agree with @NoiseFloorDev - this does look like a double transformation.

    Are you using root motion (I don't know if this matters)?
    If so - by turning off root motion in the inspector - does the hitbox still offset incorrectly?

    Edit: Where is the hit box parented in the character hierarchy? Can you show your character hierarchy?

    Also might consider looking into some of the asset packs on the store that are related (hitbox). I bet you might be able to solve based on referencing those - and possibly the supporting forum threads.
     
  12. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    @theANMATOR2b
    I tried a second hitbox with no animation, and its offset is correct.
    I am using root motion animation.
    Here is a screenshot of my hierarchy:
    EXAMPLE3.PNG
    Colliders contains the hitbox (the copy is the one I was testing with per your question)
     
  13. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    We are eliminating things. ;)

    Are you familiar with animation layer masking? IDK if this is a solution but thought I'd mention in case you are not familiar.

    The hit box is inheriting the root motion translation - based on the the test you performed.
    So - you are going to have to research parenting an animated object to a root motion controlled character - without inheriting the root motion transform.
    Does changing the animation set up root motion options in the inspector for the hit box solve?

    Root Transform Positoin (Y), (XZ)

    Alternative (probably not optimal) syncing a separate animation controller for the hit boxes with the existing character animation controller.
     
    Last edited: Aug 4, 2017
  14. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
  15. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    @theANMATOR2b this looks promising! I'm going to give it a shot and report my findings. Thanks for the help so far!
     
  16. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    @theANMATOR2b
    Unfortunately, this approach did not work--it overrides the default root motion behavior on the biped with the animator, but doesn't do anything for the collider.
    The result is the character loses root motion, and the child collider is still offset.
    Back to square one.
     
    theANMATOR2b likes this.
  17. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    Wish it was as simple as it is in 3D - uncheck do not inherit from parent - rotation,translation,scale, x,y,z.
    That would just be too easy! :(
     
  18. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    From google - it seems maybe the 'workable' solution is to move the hitbox via code - but I refuse to believe that is the ONLY solution for this. There should be a simple animation solution.

    Summoning @Mecanim-Dev
     
  19. raybarrera-aofl

    raybarrera-aofl

    Joined:
    Sep 4, 2016
    Posts:
    7
    Right??? It just seems odd that there isn't a simpler what to solve it.
    I'm doing some timeline research right now to see how that interacts with Mecanim. Animating the collider in timeline works fine, but then I have some animations in mecanim and some driven via code + timeline/playables
     
  20. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    Their is of course other solutions.
    1. Create the hit box in 3D and animate it as normal in 3D. In Unity use avatar mask to allow for humanoid retargeting.
    2. Create the hit box to be the size of the fist, parented to the hand (not animated) so when the hand shoots forward the hit box 'hits' with the fist instead of having the hit box be the size of the arm.
    3. Have the hit box positioned where the punch will occur and turn it on/off when needed. (not the best option)

    Of the 3 solutions that will solve the problem, I prefer #1, but would still like a solution that allows for the hit box to be animated without multiplying the root motion translation.
     
  21. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    Can I ask why not add capsule colliders to each bone transform? Thats how we do it in our game and that means 1:1 mappign of the colliders to the animation (The ragdoll system in Unity works the same). I guess since no one suggests this I'm missing something :D
     
    theANMATOR2b likes this.
  22. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    Even though we're using 3d models, the game is 2D, and we're using traditional 2d game hitboxes (like any fighting game out there)


    It's been quite frustrating trying to address this issue. I'm at a loss as to how one is expected to do this in Unity. Having the designer have to animate the Maya file OR animate the hitbox separately and then try to get it to match up to the character animation are awful workflows.
     
  23. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    Can you isolate the problem to a dummy mesh so you can upload a scene, so other people can look? People can only throw darts without seeing the scene, and we've run out of darts.
     
  24. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,668
    Hi @raybarrera,

    That an interesting issue, and we are wondering why you can add the hit collider in your 3d hierachy?

    Would you mind to create a smaller project exposing this issue?
     
  25. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    You could use WoldToCameraView or what the name is and mak the bone transform into a 2D space, and track the 2D colliders that way.
     
  26. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    @NoiseFloorDev @Mecanim-Dev
    I've included a unity package here for people to check out.

    Check the animation preview vs the play mode behavior. The collider is
    P1/Colliders/Punch in the AnimationTestScene
     

    Attached Files:

  27. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    Looks like a root motion problem. Notice that the transform on the root node (P1) changes during playback, but not when you scrub the animation in edit mode. I'm not familiar enough with root motion, but I think what it's doing is taking the world space motion on the pelvis and applying it to the root instead, but the collider node is outside of the humanoid skeleton, so that receives the root motion on P1, but doesn't have it factored out of itself, causing the double-transform.

    Moving the collider inside the pelvis would avoid the problem, but that's probably no good since the collider would also rotate in 3D with the pelvis. You probably want the collider to stick to the 2D plane.

    If I switch the avatar to generic, set its root transform to root1, move the collider inside root1, and re-add an animation on the collider, it seems to work. Root motion is applied to root1, the collider moves with it, but it doesn't receive any rotation. That's probably more workable.

    But I have no idea how to do that with humanoid avatars. It seems like humanoid avatars don't let you choose a root node.
     
  28. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    @NoiseFloorDev @Mecanim-Dev
    Thanks for the response. To attempt to confirm the root motion issue, I disabled it on the animation, but the issue persists. I think it's related to the humanoid vs generic rig.
    I guess my main problem with going generic would retargeting animations to our character would be difficult.

    Any thoughts?
     
  29. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    It's definitely caused by root motion. Not sure what you're testing (as far as I know there's nothing to disable that would fix the problem with humanoid), but do the test I mentioned: compare the root node's position in the animation preview to during gameplay. Animator is subtracting motion out of the pelvis and transfers it to P1, which gives the same result for the character, but causes anything not inside the character to be moved with it. (It seems like a bug that the animation preview doesn't reflect root motion, but it seems like humanoid just isn't designed with having things outside of the skeleton in mind.)

    Do you have multiple characters that you need to target the same animation to at runtime? If you only have a single character, I wouldn't use humanoid's retargetting for that--do the retargetting with an animation tool (eg. HumanIK in Maya or MotionBuilder) and export animation data that matches your actual character. You'll get a lot more control that way. If you have multiple characters and want runtime retargetting, you'll have other challenges (your hitbox animations won't be retargetted)...

    (Maybe Mr. Dev has a suggestion to make this work with humanoid?)
     
  30. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    Hey @NoiseFloorDev I just wanted to clarify what I meant about root motion in case it's relevant to the overall issue.
    The FBX was imported, and I enabled root motion and selected a dedicated root motion locator for that (it's not the pelvis). This is my animation tab on the character:


    Since the imported animation is read-only, I duplicate the animation clip to be able to animate the collider inside the same clip (or at least with the same animation data).

    What I mean by disabling root motion:


    And I can tell it actually disables the root motion because the character stops moving forward, it just animates in place with that setting off. Ditto for using a script with OnAnimatorUpdate (that box changes to read "Driven by Script" or something like that)

    Anyway, thanks--I'm still investigating the humanoid vs generic thing, as I may need multiple characters with the same animation.
     
  31. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    Disabling "apply root motion" just moves the problem to a different place: the character stops moving forward, but now the hitbox is in the right place since it's no longer having that root motion applied.

    Maybe it'll work if you change the root motion node to "root1" (I'm not sure why you have it as a separate transform, it's usually the parent of the skeleton in my experience) and put the collider inside that. I haven't tried that with your setup.
     
  32. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    Any additional thoughts? Still confused as to why this won't work on a humanoid with root motion.
     
  33. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    I already explained what's happening...
     
  34. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    205
    @NoiseFloorDev But you're not saying that's the intended behavior, right?
    You said it's root motion, but then you said it's the humanoid, then we confirmed it happens without root motion as well, so it's not really clear.
    Either way, if it were a root motion, getting the delta and applying it to the collider doesn't solve the issue. I tried every combination of local and world delta math and still could not get them to match up, so basically, I'm not convinced. Setting the root motion to "root1" doesn't work either because there is translation along all three axes, and I only want it to move on the xy plane.

    At the end of the day, going with a generic rig is not going to work for me, so that leaves me with two options:
    Write a custom hitbox editor so that I can animate a separate object on top of my character (separate animation clips/animators), or fix it with some built-in approach that I'm not aware of.

    So, I'm very appreciative of the reply and the explanation of the problem, but I'm trying to arrive at a solution.
     
  35. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    I know you're trying to arrive at a solution, but we need to understand what's happening to get to one.

    It takes the body motion (however it calculates that), subtracts it from the humanoid joints, and adds it to the root transform. I think it's working as intended, but the design just doesn't seem to take this use case into account.

    Turning off "apply root motion" wouldn't prevent it from happening, and doesn't mean that this isn't root motion. Turning that flag off just means that both the skeleton and the hitbox stop receiving any root motion. It puts the collider in the correct position (no longer receiving the double-transform), but puts the skeleton in the wrong place. In other words, it just shifts the problem. (I looked at OnAnimatorMove to see if it could be used to apply the root motion to both objets, but I don't see a way to do that. It doesn't seem to tell you what the root motion would have been if OnAnimatorMove wasn't there.)

    The only workaround I see that makes this work with humanoid is putting the hitboxes inside the skeleton (under the pelvis or the hand), but that causes a bunch of new problems. I don't know if this is a brawler or a fighter, but fighting games usually want very precisely controlled hitboxes, so having it inside the skeleton at all would be awful (you'd have to counter-key all root motion to keep the hitbox still).

    Generics seem like the solution to me, since there are other ways to retarget animations and I don't think humanoid retargetting would work since the hitboxes wouldn't be retargetted. You haven't said why you think generics won't work for you, so I can't offer much more than that, but that's the only solution I see.

    I'm not the expert, of course. @Mecanim-Dev
     
  36. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,782
    Adding capsule colliders to each bone transform does not work for this correct?
    Since the animation is created in Unity is there an option to mask the hit box - like when using a humanoid with extra bones - the extra bones are masked so the humanoid rig can still receive/retain animations via retargeting?


    How is the animation set up in the state machine? I'm guessing it is on a different layer - layer masked so as not to be combined in the same state machine as the body animations.
     
  37. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    It's a 3D animation in a 2D game, where he wants to control the hitboxes in the 2D view separately from the 3D animation. It's pretty standard in fighting games, where you want precise control over the size and motion of hitboxes, rather than having them just follow their corresponding body parts.
     
    theANMATOR2b likes this.
  38. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,668
    Hi @raybarrera,
    sorry I haven't found the time to look at this yet.
    Next week we do have a bug bash so I will have some time dedicated to investigate this issue and try to find a solution.

    Stay tuned for more news!
     
  39. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,668
    Hi @raybarrera,

    Your workflow case was really interesting and exposed some flaw that we will fix.
    The 'root' of the problem :D is effectively the root motion, when you keyframe additionnal animation in unity the animation windows sampling function doesn't write the root motion which caused this double transform.

    This is something really annoying for someone that needs to keyframe additionnal curve into unity so we will fix this.

    In the meantime here a workaround, it's not the most elegant one but it should allow you to keyframe additionnal curve.

    The goal is to mimic the root motion curve when you are keyframing so that you're additionnal curve are in you're root local space rather than global space(global space here refer to the space when you are keyframing, since root motion is not apply). Also since you are keyframing 2d object you need to be sure that there is no rotation or scale in the hierarchy that could unalign the 2d space.

    In your case since your rig is using a custom node to extract the root motion( COG_POS_LOC) you already have 50% of the answer. If you look in the animation windows you will find your root motion curve on the properties P1 : Animator.Root T
    animatorrootcurve.png

    What you need to do is
    1. Make sure that COG_POS_LOC doesn't have any rotation or scale as it would break the workaround
    2. Parent your Punch collider on your transform COG_POS_LOC
    3. Copy the curve from P1: Animator.Root T to COG_POS_LOC : Position. At this stage now any object under the COG_POS_LOC transform will be keyframed like it was under the root motion space rather than global space. This step could be automatized with a AssetPostProcessor if needed.
    4. Keyframe your collider position, scale, enable.
    5. Now the animation sould look right when you sample the clip in the animation window but should still have the double transform when you hit play.
    6. Simply rename COG_POS_LOC in the animation window to something else that doesn't exist in your hierarchy(it must turn yellow with Missing!). This way this curve won't have any effect anymore, but keep it just in case you need to tweak the collider again. To rename a curve, select it first and then click again on the name, it should turn to an edit box.
    7. Press Play

    rename_COG_POS_LOC1.png
     

    Attached Files:

unityunity