Search Unity

Mecanim Foot Placement

Discussion in 'Assets and Asset Store' started by BrUnO-XaVIeR, May 31, 2013.

  1. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Hello! I've been looking for a tool to make foot placement on Mecanim for a while now...
    I couldn't find anything, from simple to complex solutions, so I had to come up with my own thing (this is at the simple side of the rainbow):


    This basic functionality is what you see on most games, just a simple raycast based approach instead of going crazy on detailed placement.
    I mean, this is nowhere near Rune's Locomotion system, but may be of some use for your retargeted Mecanim characters.
    So I was wondering if anybody else would need this. Note that this tool is based on Mecanim IKs, so it is Unity Pro only.


    Why use this?:
    º Works with Mecanim.
    º Works on any retargeted animation.

    How it works:

    Judging by the fact that every Mecanim character requires an Agent/Controller script I decided to make this a extension for the Animator class instead of attaching one more MonoBehaviour or forcing the need to change too much code on every controller script.
    Once you have the class imported, every Animator instance you have gives you the option to use the FootPlacement() method inside of your controller script; Ideal results comes from using this inside of OnAnimatorIK().


    For basic heel placement all you need is to tell the function who the pelvis is and decide on IK weights and foot offset for fine adjustment.
    For detailed foot aligment, adding a empty GameObject on each foot is required because a reference for Raycasts is needed in world space instead of joint's local space.
    So, a controller using this function with normal aligment would be like this:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. [RequireComponent(typeof(Animator))]
    6. public class MyController : MonoBehaviour {
    7.     public bool Do;                                                       // If need to turn off placement for any reason.
    8.     public float HeelOffset;                                           // Fine adjustment of heels.
    9.     public float FeetOffset;                                           // Fine adjustment of feet.
    10.     public Transform Hips;                                            // The Pelvis joint, just a height reference.
    11.     public Transform LeftToe;                                       // Foot joint used as foot length reference.
    12.     public Transform RightToe;                                     // Foot joint used as foot length reference.
    13.     public Transform LeftTip;                                        // Empty GameObject, Joints' world space reference.
    14.     public Transform RightTip;                                      // Empty GameObject, Joints' world space reference.
    15.     private Animator Actor;                                           // The Animator component attached.
    16.     //
    17.     void Start() {
    18.         Actor = GetComponent<Animator>();
    19.     }
    20.     //
    21.     void OnAnimatorIK(int Layer) {
    22.           Actor.FootPlacement(Do,HeelOffset,FeetOffset,(Actor.GetFloat("Speed")/10),Hips,LeftToe,RightToe,LeftTip,RightTip);
    23.     }
    24. }
    25.  
    ... And the extension class will try its best to do the hard work. :)
    I did this thing in few hours and I think is not very hard to replicate it; Also, is Unity pro only so I don't know if anybody would be interested on this class. If you are interested just let me know, I may upload it for free or a very low symbolic price, dunno.
    The code is a open C# class as well, so you can modify/extend it for your particular needs.


    [Help Files]
    You can download the 'Guide' PDF from here: http://www.bedroomdeveloper.com/guides/mfp.pdf
     
    Last edited: Apr 22, 2015
    Stardog likes this.
  2. hellraizerhhh

    hellraizerhhh

    Joined:
    May 26, 2010
    Posts:
    619
    Looks pretty darn awesome. Great work
     
  3. LucasDaltro

    LucasDaltro

    Joined:
    Oct 31, 2010
    Posts:
    236
    Fabulous buddy,fabulous :')
     
  4. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,208
    Looks great - can't wait to play with it. Will it be tough to make it work with 4 feet? :)
     
  5. Archania

    Archania

    Joined:
    Aug 27, 2010
    Posts:
    1,662
    Now that is really cool. Very nice work.
     
  6. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Thanks guys.

    I didn't test with quadrupeds, but I think you can simply call animator.FootPlacement() twice,,, on the first one you set the front legs and on the second call you set the second pair of legs. :)
    The only small overhead of this is you have two raycasts for each foot, so calling the function twice isn't much of a problem.
    I will look for a quadruped Mecanim animated model and try it this weekend and see if anything must be changed for such generic rigs.

    Edit: Oh and I don't know if it has changed, but isn't Mecanim IKs for humanoids only? I need go back and read docs again, last time I checked was 2012 and IKs was for humanoids only.
     
    Last edited: Jun 1, 2013
  7. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Nice job Bruno! I recently did this myself (feel free to test it here)... mine's quite simple though, no fine adjustments.

    One thing you should keep in mind is players will almost always be using some sort of collider... and that makes it very difficult to use foot placement as you currently have... because the lower of the two feet needs to be able to reach the lower surface, but the collider won't let it. To solve this I lerp my collider center up, based on a value determined by the difference in height between the two foot raycast hits. Results in something like this:

    $foot-ik.jpg

    Also, if your character is moving you're probably going to always want to use curves to set the weights on the feet IK, otherwise when they're walking around they'll just be shuffling their feet everywhere! :)
     
  8. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,208
    That appears to be true. However, the documentation states this:

    So maybe this feature is coming at some point?
     
  9. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Yes, looks like they didn't change much since last year.
    One thing I don't like about Mecanim is that the responsible team want to do it all themselves and keep the API too much closed. That way there's nothing we can do but wait for them to add a feature someday when they want doing so.
     
  10. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    You know, you can tell the raycast a expecific layer to hit. For example, in my projects I use layer 10 for floor and layer 15 for level objects, so I tell the raycast to hit layer 10 and 15 only and it will ignore character's colliders.


    Yes, I was thinking about curves at first... But then I remember that some animation sources can't have Mecanim Curves on them, so at my case I decided to ignore this option. But is easy enough to pass to the function a curve value instead of movement speed like I did, don't even need to change the functions.
     
  11. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Oh no, I'm not referring to the raycasts interfering with the character collider, I'm referring to the collider interfering with the ground, by keeping the character too high for the lower foot to ever reach its raycast hit point. Like on ramp in your example, see here:

    $footik-bad.jpg

    You can see the ik rotation is fine, but the right foot will never reach its raycast hit position because the collider is too high on the ramp, and its not like it can "stretch" outside of the collider. But if you move the character's collider center up based on the height different of the raycast hits:

    $footik-collider-up.jpg
     
  12. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Hmm, I see. I wasn't thinking about this because all my tests was with NavMeshAgent controllers instead of CharacterControllers.
    With NavMAgents that doesn't happen.

    Doing it that way to fix this issue, you could also subtract collider height to make its ceiling to keep matching character's head.
     
    Last edited: Jun 1, 2013
  13. fano_linux

    fano_linux

    Joined:
    Jan 1, 2012
    Posts:
    909
    Very nice. This something that I want to create by my self.
     
  14. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Posts:
    1,451
    Yea this is excellent. Great job, both of you! :D
     
  15. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Thank you guys! This is in fact not very hard to do with Unity pro. lol
    The biggest deal is when you need to turn it on/off when character is jumping etc, involves a few functions to guide that or a lot of Mecanim curves on every clip you use.

    @PrimeDerektive
    That problem you posted is really related to CharacterControllers on big inclinations only. Is due to its geometry, and adjusting its center may be really annoying.
    I'm glad in my project I am doing this for NavMeshAgents only, that really doesn't happen with them. I tried a CharacterController at same character and I had to read the distance of foot to IK and use it as a offset for the controller's center:


    But for the NavMeshAgent, inclination must be more than 80º to see the IK unable to reach its goal:

     
    Last edited: Jun 1, 2013
  16. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
  17. Lax

    Lax

    Joined:
    May 14, 2012
    Posts:
    10
    Very interesting work! Do you have any videos of a character walking on an uneven terrain mesh?

    On a mesh similar to this:
    $terrain.png
     
  18. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Hi Lax. I try to not build such irregular terrains so I didn't try it with anything like that.
    But I will check it out and I can upload a video, but not today. What would be the size of a character placed on top of this mesh?

    Anyways, I'm leaving by now. I may check this out by monday or maybe this weekend.
     
    Last edited: Jun 14, 2013
  19. xandeck

    xandeck

    Joined:
    Apr 2, 2009
    Posts:
    563
    Nice work Bruno, I will also explore that :)
    Cheers
     
  20. Lax

    Lax

    Joined:
    May 14, 2012
    Posts:
    10
    Thanks! that would be great. I was thinking that a human would be simliar in scale to the capsule here:
    $preview.png
     
  21. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    @xandeck, thanks!

    Lax, I've created a simple terrain and made a fast video; The results are just the same.
    In fact if you setup the function right, feet will align to almost any kind of surface as long as your meshes are imported with correct UV normals.
    Note that on this video CharacterController is not colliding with the terrain, to make sure the alignment is absolutely visible:
    [video=youtube_share;iBXkp00Et78]http://youtu.be/iBXkp00Et78​
     
  22. Lax

    Lax

    Joined:
    May 14, 2012
    Posts:
    10
    @BrUnO XaVIeR, Thanks for creating the video, but is your foot placement only applied when the character is idle? - I'm mainly interested to see the foot placement when the character is walking on an uneven terrain. But for a standing/idle character these are definitely excellent results:)
     
  23. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    To apply detailed foot placement for when character is running or whatever, Mecanim requires you to setup custom animation curves on your animations.
    This is a slow and tedious workflow on this regards that is why I didnt record this process on the video; but no characters don't need to be idle for this to work.
    If you don't setup animation curves to tell when IKs must be enabled, Unity will animate your run/walk cycle with feet glued to the floor.
    You can check Mecanim user manual to know how you setup curves... Also I explain about it on user guide here:
    http://www.ousegames.com/guides/mfp.pdf

    That requires a bit of work to setup curves for every clip your character may have, but I didn't really find a workaround.
    The easiest thing I did was to enable IKs based on character speed, but that isn't a very realistic way of doing it.

    Also note that you can't create custom curves on .anim files. Mixamo sells a lot of these .anim files and mecanim curves won't work on them.
     
    Last edited: Jun 17, 2013
  24. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    I just noticed when I uploaded first video I wasn't using mecanim curves to control IK weights.
    Here's a video of placement always ON while adjusting IK values from custom curves to always try to place feet on floor, but still leaving feet free to playback running/walking animations:

     
  25. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Yo!
    I must say I'm surprised by the fact that some developers have already grabbed this tool from Asset Store even it been a Pro only asset; but I have no clue if these users are satisfied with the results or not or what you're doing with this thing...
    So if you are reading this and are using these methods on your project I would love to know how are you doing, if everything is running OK and a little review on Asset Store would be very nice too!

    Anyways, I do not request credits for this. If you don't want ppl to know your game/tool is using 3th party code, no problem. Enjoy it and good luck! :)
     
    Last edited: Jun 19, 2013
  26. ecurtz

    ecurtz

    Joined:
    May 13, 2009
    Posts:
    640
    I haven't bought this yet (although I will soon) because I didn't want to contaminate my own thinking about how it should work. It might be a bit of a hack, but what about comparing the foot positions to the root position as a way of determining if the foot is off the ground rather than having to add the extra curve into every animation?
     
  27. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Hi ecurtz. The functions already do that, but that doesnt change the way Mecanim IK works.
    IK control is guided by a weight value which does nothing when it is set to zero and totally overrides bone animation when set to 1.

    What curves do is tell these IKs when they should have weight of zero and when have weight set to full control.
    So, when in your animation foot is going off the floor, IK weight should be set to zero. When foot is going to impact on floor, weights should be set to 1.
    I have no idea which keyframes your animations are supposed to remove foot from the floor so I can't automate this process.
     
  28. ecurtz

    ecurtz

    Joined:
    May 13, 2009
    Posts:
    640
    My suggestion was that this could possibly be determined by looking at the (pre-IK) position of the feet and comparing those to what they'd be if they were on the "ground". However I'm now wondering if that same sort of logic can be added into an editor script to just automatically create the foot IK weight curves.

    EDIT: Bought it to play with, will let you know if I make any progress.
     
    Last edited: Jun 19, 2013
  29. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Oh, got it. I really don't know if doing that is possible with current Mecanim API been so closed source.
    I will also investigate possibilities, if you manage to solve this would be great because I also hate to stop by and setup all those curves...
    Good luck!
     
  30. ecurtz

    ecurtz

    Joined:
    May 13, 2009
    Posts:
    640
    This definitely looks worth investigating further...

    Code (csharp):
    1.  
    2.         animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, (animator.pivotWeight < 0.51f) ? 1f:0f);
    3.         animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, (animator.pivotWeight > 0.49f) ? 1f:0f);
    4.  
     
  31. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Cool. I can't try it right now 'cause is already late night here, but I will experiment with that pm as soon as possible!
     
  32. kenshin

    kenshin

    Joined:
    Apr 21, 2010
    Posts:
    940
    Really a nice idea Bruno!
     
  33. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Thank you kenshin!

    @ecurtz, answered pm! That's a really cool idea, will wait for your reply before sending an update for the package.
     
  34. marcaurelio74

    marcaurelio74

    Joined:
    Sep 2, 2012
    Posts:
    60
    Hi really interesting asset!
    I'm principally interested in the foot placement on uneven terrain while Walking/Running, do you plan to implement foot prediction to optimize your system?
     
  35. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Hi. Yes, I plan to implement prediction in future, but is the kind of thing I can't do for now. Need to research and experiment with that and I can't start something like that at this moment.
     
  36. marcaurelio74

    marcaurelio74

    Joined:
    Sep 2, 2012
    Posts:
    60
    Thanks for your reply.
    I think your asset is a big step in the right direction to have a proper Locomotion system in Mecanim.

    Last question's :
    1) To apply your system is not necessary to add a rigidBody to character, right?
    2) Using the navmesh controller instead of a Character Controller is fine?
     
  37. ProMaXoid

    ProMaXoid

    Joined:
    Jun 22, 2013
    Posts:
    3
    For run or walk support you can use this tool. I have try it yesterday and it looks great.
     
    Last edited: Jun 22, 2013
  38. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    @ProMaXoid that looks interesting.

    So. Guys I submited an update with a bit of improvements, added functions to allow easier use of LayerMasks as some was telling me that is needed and also added a code variation courtesy of Eli Curtz where you don't need to setup FBX Curves if you don't want to.
    UT will take a bit of a time to update the package, so... Till later, cheers!
     
  39. ProMaXoid

    ProMaXoid

    Joined:
    Jun 22, 2013
    Posts:
    3
    @BrUnO XaVIeR no, that looks great since you don't need to code something if you do not want to - you can just use user-friendly drag'n'drop;))
     
  40. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Cool! Being that great I would charge way more than $30 bucks for that.
     
  41. ecurtz

    ecurtz

    Joined:
    May 13, 2009
    Posts:
    640
    I may buy the other one as well just to be thorough, but I'm getting pretty good results with no added curves after a few tweaks.
     
  42. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    1.1 is up on Asset Store :)
    As soon as I finish some nasty problems with other duties, I'm going to work on some more stuff I want to add on this. Till later!
     
  43. ecurtz

    ecurtz

    Joined:
    May 13, 2009
    Posts:
    640
    I just sent BrUnO XaVIeR an update to my lazy person's version (no animation curve editing required) which is significantly improved, so hopefully that will be in the next update as well.
     
  44. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Guys, thanks to Ecurtz efforts, soon I will upload an update where you can adjust IK weights through curves on your character's inspector (instead of importing FBX curves) or leave it untouched and the class will create a pair of default curves for you so you can just forget about messing around with curves if you don't like doing so.

    Will submit soon :)
     
  45. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    1.2 is up on Asset Store.
    We have now a much better automated method for generic walk/run animation clips while foot-planting. Check out the doc notes! :)

    Once I can, will start research on foot step prediction to have even more natural leg movement while avoiding floor obstacles.
    Till later!
     
  46. Play_Edu

    Play_Edu

    Joined:
    Jun 10, 2012
    Posts:
    722
    good work
     
  47. JohnPet

    JohnPet

    Joined:
    Aug 19, 2012
    Posts:
    85
    You know, you could code a climbing system similar to Assassin's Creed III with this way. There is a video online where the devs are talking and showing how their system works. You should try it.
     
  48. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    BlackJonima, I know; the GDC talk.
    This is the master plan, but I'm going one step at a time. That system did cost them more than 3 years of development and they already had Autodesk's Human IK implemented.
    Mecanim IK is like a half baked human IK system and makes things like that much harder to achieve than if it were a full body IK solver.
    So this is not a very easy task to go into, but I want to keep going developing this until we have that kind of amazing procedural IK animations.
     
  49. JohnPet

    JohnPet

    Joined:
    Aug 19, 2012
    Posts:
    85
    Yep, deffinately not an easy task. But at the end, it will be an amazing system worth the time, and the money if you decide to sell it.
     
  50. JPM1987

    JPM1987

    Joined:
    Jul 11, 2013
    Posts:
    3
    Can anyone tell me how to get the PositionWeight and RotationWeight for FootPlacementV2()?

    The image is cut off on this part.