Search Unity

FINAL IK - Full Body IK, Aim, Look At, FABRIK, CCD IK... [1.0 RELEASED]

Discussion in 'Assets and Asset Store' started by Partel-Lang, Jan 15, 2014.

  1. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    This asset is really tempting...
    I know this should be asked elsewhere, but I'm curious at how well this plays with BOLT?
     
  2. SkyMageTheWise

    SkyMageTheWise

    Joined:
    Apr 27, 2014
    Posts:
    3
    Hi Partel!

    I had a little trouble getting my Rigify character working with the HeadEffector component at first, but after reimporting my character, everything worked immediately. I think the difference was that in Unity5, I didn't use the "rigify to unity" asset. That's just my best guess :)

    edit: What I mean to say is that *without* the rigify-to-unity asset, final IK had an easier time discovering the appropriate bones.
     
  3. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi, sorry for the delay,

    About the rotation issue.. Are you sure the weight curve for "Rotation Weight" or "Rotate Bone Weight", whichever you are using to rotate the hand, is exactly 1 or greater at the time of pick up? It is very difficult to set exact values with Unity's curve editor and if it is less than 1, the hand might not be rotated exactly to match the rotation of the target. I made a test scenario where the dummy is picking up a rapidly rotating object and the angular error is always somewhere around e-07, which comes from Quaternion to Euler conversion and is not visible, so I'm having difficulty reproducing the problem. Would it be possible for you to send me a repro or something?

    The dummy and your model's hand is rotated differently probably because their hand bones are oriented differently. Some models have hand bone X axis pointing towards the fingers, some models have Y or Z, if the bone orientations are different, then the targets needs to be reoriented as well.

    About pulling characters, I have not tried this myself so I don't know for sure which solution will work the best. You probably want to drag a ragdoll around? In this case I'd try something like this:

    1. Attach a kinematic rigidbody to char #1 somewhere in front of him.
    2. Add a (spring) joint to that rigid body that connects it with one of the bones of the rag doll.
    3. Use IK (with either the Interaction System or just pinning the effectors) to place the hands of char #1 on the rag doll.

    Now if you move char #1 around, the kinematic rigidbody attached to it will also pull the rag doll along. You can adjust the spring value of the joint to release or hold more tight.

    Hi, Sluice.
    I have not tried Bolt myself, but some other people apparently have.
    Normally, when networking, each client calculates it's IK independently so you wouldn't have to sync solved bone rotations or whatever. So for example you sync your character positions and aiming targets like you normally would, then each client will solve their own AimIK to make the characters aim at the targets.

    Hey, glad you found a solution! :)

    Cheers,
    Pärtel
     
    sluice likes this.
  4. Becoming

    Becoming

    Joined:
    May 19, 2013
    Posts:
    781
    If this is version 0.5 and it is that awesome, what will the final version be like? Do you have something like a roadmap or a list of things you will add? Also when do you think that version 1 will hit the assetstore? I dont think there is anything missing or so, i am just curious.
     
  5. unitywlp

    unitywlp

    Joined:
    Jan 3, 2014
    Posts:
    146
    Hi i was using aim weapon with final ik i was not able to setup aim using the playmaker it was not having any playmaker demos i want use aim weapon with mechanim is it possible to use aim weapon using mechanim aimation system thanks
    tutorial will be fine
     
  6. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Thanks!
    Its still a "beta" mainly because I haven't bothered to remove the label from the Asset Store images. :) With more than 1K users, its safe to say it has been battle-tested (at least the core features that have been there for some time).

    About the roadmap, I have tons of ideas for FinalIK, more than I could ever possibly realize, but for the next version (that will probably be 1.0) I hope to create a more generic version of FullBodyBipedIK (FullBodyGenericIK) that would work with any creature. Then I want to make some 2D solvers, improve the Grounder and Interaction System, make some kind of a solution to solve the fingers. Improvements to documentation and a dedicated support forum and a proper web page are also on the map..

    Hi!

    To get started just follow these instructions:

    1. Attach AimIK component to the root of the character.
    2. assign the spine bones of the character as the "Bones" of AimIK
    3. assign the gun as the "Aim Transform"
    4. set "Axis" to be the local axis of the gun that points towards the end of the barrel
    5. make an empty game object, assign it as the "Target" of AimIK

    Now you can use Playmaker to just move the target game object to wherever you need and you can use the AimIK Playmaker action to weigh it off and on.
    Also, you need to have a forward aiming animation playing on that character.

    Regards,
    Pärtel
     
    WendelinReich likes this.
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    How do we prevent a biped character's hands from intersecting his head/body/legs?

    Here's what I tried: I added a SphereCollider to the head, another to the hand, and a (non-kinematic) Rigidbody to each. But they still pass through each other. (My various limb targets etc. are driven from a Kinect sensor.)

    I have tried various settings for Interpolate and Collision Detection on the Rigidbodies, but they have no effect. Both objects are in the Default layer, and I've confirmed that Default collides with Default in the physics settings. In fact I even tried placing a cube, with a standard BoxCollider and Rigidbody setup, next to the avatar; I can punch this cube and send it flying with either my head or my hand. Yet hand and head still pass through each other without even twitching.

    Any idea what I'm missing here?
     
  8. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi!

    They probably pass through each other because you move those rigidbodies in LateUpdate, so there is no physics step to apply the collisions before you update your hand IK positions.

    I wound try raycasting instead. Just add colliders to the head and body bones like you probably already have. Then, before you set your hand IK targets, raycast from the animated position of the hand (ik.solver.leftHandEffector.bone.position) to where you want to put it, and if it collides, set IK target position to hit point instead.

    Cheers,
    Pärtel
     
  9. SunnySunshine

    SunnySunshine

    Joined:
    May 18, 2009
    Posts:
    976
    Hi Partel,

    I have a problem with LookIK. I'm not using any animation on my characters head. Instead, it is controlled through script. Right now I do something like this:

    1. FixTransforms (manually)
    2. Process my own code for controlling head
    3. LookIK.Update (manually)

    The problem is that even though weight is 1, changes from step 2 seems to carry through to LookIK. I was under the impression that a solver will override all animation for its transforms to fulfill its goal if its weight is 1? Is that not how it works? Because right now, there are times when LookIK with weight 1 will result in the character not looking at the target.

    Basically what I want to do is lerping from my result in step 2, to the transforms of looking at a target.
     
    Last edited: Mar 16, 2015
  10. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi!

    It might be just the "Clamp Weight Head" kicking in at far off angles. Set it to zero and see what happens.
    Also make sure "Head Weight" is set to 1.

    If thats not it, try replacing LookIK.solver.Update with just head.rotation = Quaternion.identity;
    Then let me know if the head stays completely fixed in world space or is rotating in any way.

    Cheers,
    Pärtel
     
  11. SunnySunshine

    SunnySunshine

    Joined:
    May 18, 2009
    Posts:
    976
    I don't think it has to do with clamp weight. I tried playing with the sliders but they didn't affect the outcome.

    Using quaternion identity will indeed make it stay fixed, but the angle is awkward. :)

    I made a very simple test case:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. public class LookIKTest : MonoBehaviour
    6. {
    7.     public LookAtIK ik;
    8.  
    9.     public Transform head;
    10.     public Vector3 headRotate;
    11.  
    12.     // Use this for initialization
    13.     void Start ()
    14.     {
    15.         ik.Disable();
    16.     }
    17.    
    18.     // Update is called once per frame
    19.     void Update ()
    20.     {
    21.         ik.solver.FixTransforms();
    22.  
    23.         head.Rotate(headRotate);
    24.  
    25.         ik.solver.Update();
    26.     }
    27. }
    28.  
    If headRotate is zero, it works fine. But if I add a rotation to it, especially if it is large, then ik.solver.Update() will not accurately rotate towards target even though weight is 1.

    http://i.imgur.com/N16YoAp.png
     
  12. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi again,

    First, it was probably a typo, but you need to use LateUpdate instead of Update, otherwise animation will override everything.

    In the screenshot the head is missing the target because it is rotated so far off before IK solves, the "Clamp Weight Head" kicks in and limits it so that the target can not be reached. If you set clamp weight head to 0, the head will be looking at the target, but it's tilted. Thats because LookAtIK tries to maintain the animated tilt of the head as much as possible and by rotating the head with the script, the tilt is also awkward.

    If you want LookAtIK to always reach the same conclusion, you should call ik.solver.FixTransforms() right before ik.solver.Update(), so it would be like this:

    Code (CSharp):
    1. head.Rotate(headRotate);
    2.  
    3.         ik.solver.FixTransforms();
    4.         ik.solver.Update();
    But it would not enable you to smoothly lerp from head.Rotate to IK-controlled behaviour.

    One way to solve this would be to just fix the tilt angle of the head by keeping the head's up axis locked:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. public class LookIKTest : MonoBehaviour
    6. {
    7.     public LookAtIK ik;
    8.    
    9.     public Transform head;
    10.     public Vector3 headRotate;
    11.  
    12.     [Range(0f, 1f)] public float fixTiltWeight = 1f;
    13.     public bool useAnimatedHeadUp;
    14.     public Vector3 headUpAxis = Vector3.up; // Assign this to be the local axis of the head that is facing up
    15.    
    16.     void Start ()
    17.     {
    18.         ik.Disable();
    19.     }
    20.    
    21.     void LateUpdate ()
    22.     {
    23.         Vector3 headUp = useAnimatedHeadUp? head.rotation * headUpAxis: Vector3.up;
    24.  
    25.         ik.solver.FixTransforms();
    26.  
    27.         head.Rotate(headRotate);
    28.  
    29.         // Fixing the head up axis to either where it was in the animation or Vector3.up.
    30.         if (fixTiltWeight > 0f) {
    31.             Quaternion fixTilt = Quaternion.FromToRotation(head.rotation * headUpAxis, headUp);
    32.             fixTilt = Quaternion.Slerp(Quaternion.identity, fixTilt, fixTiltWeight);
    33.  
    34.             head.rotation = fixTilt * head.rotation;
    35.         }
    36.  
    37.         ik.solver.Update();
    38.     }
    39. }
     
    SunnySunshine likes this.
  13. SunnySunshine

    SunnySunshine

    Joined:
    May 18, 2009
    Posts:
    976
    Ah I see, thank you.
     
  14. RFLG

    RFLG

    Joined:
    Feb 7, 2011
    Posts:
    153
    Hi Partel,

    Thanks for all the help!

    Concerning the rotation issue, you where right, I forgot to add a weight curve for "Rotation Weight", adding one with 1 at the time of pick up fixed it! Now it's perfect regardless of the target-object's position.

    Concerning the "pull-and-drag" situation, I've found a mixed solution using your tips and some procedural movement. It works but I'd like your help to tweak it further. This is process I'm using now:

    1-Char #1 reaches and grabs char #2.
    2-I pause the IK interaction on grab
    3-I proceduraly move Char #2 to a designated point (a "destination" GO parented to Char #1)

    This wraps up the reach-grab-pull part I needed. But here is where I need your help.

    I'm triggering the procedural bit on step 3 with a keypress on my tests, but I needed it to be triggered automaticaly, lets say on the moment that the interaction gets paused. I would also like it to be controlled by the IK interaction instead of using colliders.

    So, my questions are:

    -Are there any events or IK states I can listen/monitor on my own scripts to know when the interaction is paused? This way I could add all the control layers I need without having to tamper your sources and risk breaking something :)

    -Also, I can call the Stop() and Resume() methods on the InteractionEffector.cs to "finish" the interaction after I do my procedural bit? Or should I do it some other way?

    Again, thank you for the help in using Final IK! It is a great adition to our project and is enabling us to take it to a whole new level!
     
  15. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi again!

    The first question about events, yes, take a look at your Interaction Object, below the "Weight Curves" and "Multipliers" are "Events". Expand "Messages" in the same event that you are using to pause the interaction, you can define a function name and the game object that it will be called on (using GameObject.SendMessage();)
    Alternately, should you prefer delegates, you can add to the InteractionSystem.OnInteractionPause.

    The second question, yes you can use InteractionSystem.ResumeAll(); for that.

    Cheers,
    Pärtel
     
  16. srgcrafty

    srgcrafty

    Joined:
    Sep 2, 2014
    Posts:
    1
    Hey Partel,

    I am attempting to use your software to facilitate grabbing of objects in Unity using the Razer Hydra, and I am hitting a few roadblocks. I went through the tutorials, specifically the one regarding reaching out and grabbing of an object, shaping the hand around it so that it looks natural. I was wondering if there is a way to get this hand molding functionality without the use of the entire FullBodyIK rig?

    Thanks a lot,

    - Jack
     
    Last edited: Mar 17, 2015
  17. RFLG

    RFLG

    Joined:
    Feb 7, 2011
    Posts:
    153
    Hi Partel,

    Just to let you know that everything is working perfectly and we are off to integrate this on our game! So thank you for all the help and for making this great component ;) I'll be sure to follow this thread, since this is a very interesting topic and we can't wait for what the next updates will bring!
     
  18. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi, Jack,
    Yes, if you don't need the full body effect, you can use the LimbIK component instead, it's basically the same logic. Or you can set FullBodyBipedIK solver iterations to 0, which would disable full body solving and hence speed things up considerably. The HandPoser script works either way should you need it.
    What exactly are the roadblocks you've been hitting?

    I'd send you a demo, but I don't have a Razer because I've been waiting forever for their STEM system but it seems it's taking them slightly longer than forever. :)

    Cheers,
    Pärtel
     
  19. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey, great to hear that! Good luck with your game and I can't wait to see it published! :) Then I can add it to my secret list of games that are using Final IK, somewhere next to Illusion - Harem Mate and Amazing Frog :)
     
  20. Alphalpha

    Alphalpha

    Joined:
    Oct 9, 2013
    Posts:
    74
    Wasn't expecting that reference here! o_O If they've adopted FinalIK their animations must be to die for (Shakespeare double entendre) now! :p That should cause a rise in customers. At least it couldn't do any harem, knock on wood.

    But you're probably just jerking my chicken, er, chain.


    Sorry, I... I don't know what came over me. :oops:
     
  21. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Haha, no chicken.. apparently they have implemented FBBIK for posing the avatars. In this trailer you can see it in action (at 0.17). :)
     
  22. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey all,
    Long time no video:
     
    WendelinReich and OnePxl like this.
  23. lazygunn

    lazygunn

    Joined:
    Jul 24, 2011
    Posts:
    2,749
    That is absolutely brilliant and an amazing way to get people (me included) thinking more about networked VR
     
    Partel-Lang likes this.
  24. Becoming

    Becoming

    Joined:
    May 19, 2013
    Posts:
    781
    Nooo, i wanted to be the first to do that :D
     
    Partel-Lang likes this.
  25. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Thanks! Head position and rotation can be synced over the network, but its a bit trickier for moving characters. When people walk, they don't have their head completely fixed on the y axis like chicken. Looks unnatural. But I guess it could be resolved by disabling head position pinning for the other characters when they move and going for rotation only, DK1 style.
     
  26. Becoming

    Becoming

    Joined:
    May 19, 2013
    Posts:
    781
    Solved with Final IK?

    I guess additive motion could work as well. I really look forward when we finally get to the characteranimations in our project!
     
  27. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Haha, I should rename the head effector to "Chicken IK" :)
     
  28. khos85

    khos85

    Joined:
    Jul 21, 2013
    Posts:
    541
    Very nice, would you be willing to share a/the sample ? I'd like to understand how setup that.
     
  29. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Of course, the video was made with one of the scenes in the Final IK OVR add-on, which you can download from below:
    Unity 4
    Unity 5
     
  30. Alphalpha

    Alphalpha

    Joined:
    Oct 9, 2013
    Posts:
    74
    That's pretty cool, man. You're catching some exotic fish in your ever-expanding net woven by IK powered robo-spiders.
     
    Partel-Lang likes this.
  31. davdun

    davdun

    Joined:
    Mar 17, 2015
    Posts:
    9
    Could this be extended with the HTC vives 2 trackable hand controllers? Perhaps you could derive the average center of mass of the biped from these 3 trackable points to get an approximate avatar for someone else in some sort of multi-player VR game. It would certainly help with immersion, the alternative is to have floating head and hands for the other players in VR space.
     
  32. OrdinaryDev83

    OrdinaryDev83

    Joined:
    May 8, 2014
    Posts:
    23
    Hi, i'm making a game and i tried Final IK, but, i can't handle by Script Final IK (LookAtIK).
    I can't by a variable, assign LookAtIK to it. (Javascript).
     
  33. ohohgames

    ohohgames

    Joined:
    Aug 9, 2014
    Posts:
    23
    Hi, I'm using Final IK to apply to my game which allows me to control octopus tails. But currently there is a limitation which cause me headache for hours. I'm using ik.solver.SetIKPosition to set the target position, if the target position is within the range of the tail then it work as expected. But if the target postion is further than the range then the tail can not physically reach the destination.
    So is there a way to modify IKSolverFABRIK so that the tail's mesh can be stretched to reach the target IK position.
    Using FABRIKRoot can not achieve what I expected either because many tails should be stretched to different IK target postion at the same time.

     
    Last edited: Mar 22, 2015
  34. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    Hi Pärtel, what's the recommended way of smoothly fading in/out the effect of GrounderQuadruped? Setting "weight" of GrounderQuadruped to something lower than 1 results in weird foot/leg placement, and adjusting the position weights of the four individual LimbIK components has no effect. (Also, neither LimbIK nor its "solver" member have a "weight" member... what am I missing?)
    Thanks! /W
     
  35. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi,
    It can be extended to any hand controller. It is using the Full Body Biped IK so the hand effectors are yours to pin to whatever you need. :)

    Hi!
    Javascript users need to move the entire "RootMotion" folder to the "Assets/Plugins" folder (like you would with any other C# package you wish to refer to from Javascript). Then create "Assets/Editor" and move all the scripts from "Assets/Plugins/RootMotion/FinalIK/Editor" and "Assets/Plugins/RootMotion/Scripts/Editor" there. Its like that if you have Final IK 0.5, the earlier versions had a bit different folder layout, the editor scripts were more scattered.

    Hi!

    Yes you can stretch a FABRIK chain, try this code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. public class FABRIKStretch : MonoBehaviour {
    6.  
    7.     public FABRIK ik;
    8.     public Transform target;
    9.     [Tooltip("Set this to false only if you are using it on an animated character that has scale keys for the bones in the chain")] public bool fixedChainLength = true;
    10.     [Range(1f, 10f)][Tooltip("This is not distance, but multiplier of chain length")] public float maxStretch = 2f;
    11.  
    12.     private Vector3 defaultLocalScale;
    13.     private float chainLength;
    14.  
    15.     void Start() {
    16.         defaultLocalScale = ik.solver.bones[0].transform.localScale;
    17.  
    18.         UpdateChainLength();
    19.     }
    20.  
    21.     void LateUpdate() {
    22.         if (!fixedChainLength) UpdateChainLength();
    23.  
    24.         Vector3 dir = target.position - ik.solver.bones[0].transform.position;
    25.         float mag = dir.magnitude;
    26.  
    27.         float stretch = Mathf.Clamp(mag / chainLength, 1f, maxStretch);
    28.  
    29.         ik.solver.bones[0].transform.localScale = stretch * defaultLocalScale;
    30.     }
    31.  
    32.     private void UpdateChainLength() {
    33.         chainLength = 0f;
    34.  
    35.         for (int i = 0; i < ik.solver.bones.Length - 1; i++) {
    36.             chainLength += ik.solver.bones[i].length;
    37.         }
    38.     }
    39.  
    40. }
    41.  
    Hi again, WendelinReich,
    Can you elaborate, what do you mean by weird foot/leg placement when the weight is < 1? I'm looking at my Grounder demo with the wolf and blending weight to 0 just smoothly interpolates the feet from their grounded positions to their animated positions, as expected..
     
  36. ohohgames

    ohohgames

    Joined:
    Aug 9, 2014
    Posts:
    23
    @Partel Lang : thank you, that's work like charm. Here is a slightly modified version so that the the mesh doesn't scale.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. public class FABRIKStretch : MonoBehaviour {
    6.    
    7.     public FABRIK ik;
    8.     public Transform target;
    9.     [Tooltip("Set this to false only if you are using it on an animated character that has scale keys for the bones in the chain")] public bool fixedChainLength = true;
    10.     [Range(1f, 10f)][Tooltip("This is not distance, but multiplier of chain length")] public float maxStretch = 2f;
    11.    
    12.     private Vector3 defaultLocalScale;
    13.     private float chainLength;
    14.     private Vector3[] positions;
    15.    
    16.     void Start() {
    17.         defaultLocalScale = ik.solver.bones[0].transform.localScale;
    18.         positions = new Vector3[ik.solver.bones.Length];
    19.         UpdateChainLength();
    20.     }
    21.    
    22.     void LateUpdate() {
    23.         ik.solver.SetIKPosition(target.position);
    24.    
    25.         if (!fixedChainLength) UpdateChainLength();
    26.        
    27.         Vector3 dir = target.position - ik.solver.bones[0].transform.position;
    28.         float mag = dir.magnitude;
    29.        
    30.         float stretch = Mathf.Clamp(mag / chainLength, 1f, maxStretch);
    31.        
    32.         ik.solver.bones[0].transform.localScale = stretch * defaultLocalScale;
    33.        
    34.         int i = 0;
    35.         foreach(IKSolver.Bone bone in ik.solver.bones) {
    36.             positions[i++] = bone.transform.position;
    37.         }
    38.        
    39.         ik.solver.bones[0].transform.localScale = defaultLocalScale;
    40.        
    41.         i = 0;
    42.         foreach(IKSolver.Bone bone in ik.solver.bones) {
    43.             bone.transform.position = positions[i++];
    44.         }
    45.     }
    46.    
    47.     private void UpdateChainLength() {
    48.         chainLength = 0f;
    49.        
    50.         for (int i = 0; i < ik.solver.bones.Length - 1; i++) {
    51.             chainLength += ik.solver.bones[i].length;
    52.         }
    53.     }
    54.    
    55. }
    56.  
     
    Partel-Lang likes this.
  37. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Hi Partel. I'm in the process of upgrading our project to use UMA2 everything seems to be working ok so far but FinalIK is throwing some errors, not sure if it's because of a compatibility issue with UMA2 or if I did something wrong.

    NullReferenceException: Object reference not set to an instance of an object
    RootMotion.FinalIK.IKMappingLimb.SetLimbOrientation (Vector3 upper, Vector3 lower) (at Assets/_AssetPackages/RootMotion/FinalIK/IK Solvers/IKMappingLimb.cs:83)
    RootMotion.FinalIK.IKSolverFullBodyBiped.SetLimbOrientation (FullBodyBipedChain chain, RootMotion.LimbOrientation limbOrientation) (at Assets/_AssetPackages/RootMotion/FinalIK/IK Solvers/IKSolverFullBodyBiped.cs:470)
    RootMotion.FinalIK.IKSolverFullBodyBiped.SetLimbOrientations (RootMotion.BipedLimbOrientations o) (at Assets/_AssetPackages/RootMotion/FinalIK/IK Solvers/IKSolverFullBodyBiped.cs:454)
    NN.Controller.InteractionController.SetupIK () (at Assets/_GameAssets/Scripts/NN/Character Controller/InteractionController.cs:163)
    NN.Controller.InteractionController.Start () (at Assets/_GameAssets/Scripts/NN/Character Controller/InteractionController.cs:51)

    NullReferenceException: Object reference not set to an instance of an object
    RootMotion.FinalIK.InteractionEffector.Initiate (RootMotion.FinalIK.InteractionSystem interactionSystem, RootMotion.FinalIK.IKSolverFullBodyBiped solver) (at Assets/_AssetPackages/RootMotion/FinalIK/InteractionSystem/InteractionEffector.cs:48)
    RootMotion.FinalIK.InteractionSystem.Start () (at Assets/_AssetPackages/RootMotion/FinalIK/InteractionSystem/InteractionSystem.cs:417)

    NullReferenceException: Object reference not set to an instance of an object
    RootMotion.FinalIK.InteractionEffector.ResetToDefaults (RootMotion.FinalIK.IKSolverFullBodyBiped solver, Single speed) (at Assets/_AssetPackages/RootMotion/FinalIK/InteractionSystem/InteractionEffector.cs:66)
    RootMotion.FinalIK.InteractionSystem.LateUpdate () (at Assets/_AssetPackages/RootMotion/FinalIK/InteractionSystem/InteractionSystem.cs:500)
     
  38. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi again, Hedonsoft,

    I just downloaded UMA2, imported Final IK to the project, opened the "Scene01 - crowd" scene, picked a character, added this component to it in runtime (to the game object that has the Animator):

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK; // Need to include the RootMotion namespace as well because of the BipedReferences
    4. using RootMotion;
    5.  
    6. public class AddFBBIKInRuntime : MonoBehaviour {
    7.  
    8.     void Start() {
    9.         AddFBBIK(gameObject);
    10.  
    11.         Destroy(this);
    12.     }
    13.  
    14.     // Call this method whenever you need in runtime.
    15.     // Please note that FBBIK will sample the pose of the character at initiation so at the time of calling this method,
    16.     // the limbs of the character should be bent in their natural directions.
    17.     void AddFBBIK (GameObject go, BipedReferences references = null) {
    18.         if (references == null) { // Auto-detect the biped definition if we don't have it yet
    19.             BipedReferences.AutoDetectReferences(ref references, go.transform, BipedReferences.AutoDetectParams.Default);
    20.         }
    21.  
    22.         FullBodyBipedIK ik = go.AddComponent<FullBodyBipedIK>(); // Adding the component
    23.         // Set the FBBIK to the references. You can leave the second parameter (root node) to null if you trust FBBIK to automatically set it to one of the bones in the spine.
    24.         ik.SetReferences(references, null);
    25.         // Using pre-defined limb orientations to safeguard from possible pose sampling problems (since 0.22)
    26.         ik.solver.SetLimbOrientations(BipedLimbOrientations.UMA); // The limb orientations definition for UMA skeletons
    27.         // or...
    28.         //ik.solver.SetLimbOrientations(BipedLimbOrientations.MaxBiped); // The limb orientations definition for 3ds Max Biped skeletons
    29.         // or..
    30.         //ik.solver.SetLimbOrientations(yourCustomBipedLimbOrientations); // Your custom limb orientations definition
    31.         // To know how to fill in the custom limb orientations definition, you should imagine your character standing in I-pose (not T-pose) with legs together and hands on the sides...
    32.         // The Upper Bone Forward Axis is the local axis of the thigh/upper arm bone that is facing towards character forward.
    33.         // Lower Bone Forward Axis is the local axis of the calf/forearm bone that is facing towards character forward.
    34.         // Last Bone Left Axis is the local axis of the foot/hand that is facing towards character left.
    35.     }
    36. }
    Worked nice and smooth..
    can you send me the code that you use for setting up IK?

    Cheers,
    Pärtel
     
  39. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    If I set the references in Update() they get set fine (Did this just to test) But if I put it in Start() or even do a references=null check it still won't set my references. I'm adding my Interaction controller last avter my UMA is generated.

    InteractionController.cs

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using RootMotion;
    5. using RootMotion.FinalIK;
    6.  
    7. namespace NN.Controller
    8. {
    9.     public class InteractionController : MonoBehaviour
    10.     {
    11.         public Controller controller;
    12.         public GameObject uma;
    13.  
    14.         // Other final ik stuff
    15.         public bool UseIK = true;
    16.         public FullBodyBipedIK ik;
    17.         public BipedReferences references=null;
    18.  
    19.         // Interaction stuff
    20.         public InteractionSystem interactionSystem;
    21.  
    22.         // AimIK stuff
    23.         public GameObject currentWeapon;
    24.         public AimIK aimIK;
    25.         private Transform targetTransform;
    26.         private Vector3 targetPosition;
    27.  
    28.         // Left hand positioning stuff
    29.         private IKEffector RightHand { get { return ik.solver.rightHandEffector; } }
    30.         private IKEffector LeftHand { get { return ik.solver.leftHandEffector; } }
    31.         private Quaternion relativeRotation;
    32.  
    33.         // LookAtIK stuff
    34.         public LookAtIK lookAtIK;
    35.  
    36.         public NN.UMAScripts.Avatar avatar;
    37.         public string gender;
    38.  
    39.         // Use this for initialization
    40.         void Start()
    41.         {
    42.             avatar = GetComponent<NN.UMAScripts.Avatar>();
    43.             gender = avatar.GetGender(); //Returns MaleHuman or FemaleHuman that has the animator
    44.  
    45.             SetReferences();
    46.         }
    47.  
    48.         void Update()
    49.         {
    50.             // update Aim point
    51.             if (!controller.InNetwork || (controller.photonViewRef != null && controller.photonViewRef.isMine))
    52.             {
    53.                 targetTransform.position = controller.playerUI.AimPoint;
    54.                 if(controller.photonViewRef != null)
    55.                     controller.photonViewRef.RPC("SetTargetPosition", PhotonTargets.Others, new object[] {targetTransform.position.x, targetTransform.position.y, targetTransform.position.z });
    56.             }
    57.             else
    58.             {
    59.                 targetTransform.position = targetPosition;
    60.                 return;
    61.             }
    62.  
    63.             ProcessActivation();
    64.  
    65.             // DEBUG: KeyCode.F needs to be assigned to proper key, and check for network
    66.             if (Input.GetKeyDown(KeyCode.F))
    67.             {
    68.                 if (controller.InNetwork) // In Network
    69.                 {
    70.                     if (controller.photonViewRef.isMine)
    71.                         controller.photonViewRef.RPC("ToggleAim", PhotonTargets.All, !Aiming);
    72.                 }
    73.                 else // Not in Network
    74.                     ToggleAim();
    75.             }
    76.         }
    77.  
    78.         void LateUpdate()
    79.         {
    80.             // For debugging in the inspector
    81.             if (ik != null)
    82.             {
    83.                 //   ik.solver.leftHandEffector.positionOffset = domHandOffset;
    84.             }
    85.  
    86.             // Update LookAt
    87.             lookAtIK.solver.IKPosition = targetTransform.position;
    88.             lookAtIK.solver.Update();
    89.          
    90.             // Update aim if aiming
    91.             if (Aiming)
    92.             {
    93.                 Vector3 toLeftHand = LeftHand.bone.position - RightHand.bone.position;
    94.                 Vector3 toLeftHandRelative = RightHand.bone.InverseTransformDirection(toLeftHand);
    95.                 relativeRotation = Quaternion.Inverse(RightHand.bone.rotation) * LeftHand.bone.rotation;
    96.  
    97.                 aimIK.solver.IKPosition = lookAtIK.solver.IKPosition;
    98.                 aimIK.solver.Update();
    99.  
    100.                 // Position left hand
    101.                 LeftHand.position = RightHand.bone.position + RightHand.bone.TransformDirection(toLeftHandRelative);
    102.                 LeftHand.positionWeight = 1f;
    103.  
    104.                 // Make sure right hand bone won't budge
    105.                 RightHand.position = RightHand.bone.position;
    106.                 RightHand.positionWeight = 1f;
    107.                 ik.solver.GetLimbMapping(FullBodyBipedChain.RightArm).maintainRotationWeight = 1f;
    108.             }
    109.  
    110.             ik.solver.Update();
    111.         }
    112.  
    113.         private void OnPostFBBIK()
    114.         {
    115.             if (Aiming)
    116.                 LeftHand.bone.rotation = RightHand.bone.rotation * relativeRotation;
    117.         }
    118.  
    119.         public void OnTriggerEnter(Collider c)
    120.         {
    121.             Debug.Log("Trigger: " + c.gameObject.name);
    122.         }
    123.  
    124.         public bool Aiming { get; set; }
    125.  
    126.         /// <summary>
    127.         /// Initialize and adds all IK components
    128.         /// </summary>
    129.         public void SetReferences()
    130.         {
    131.             if (references == null)
    132.             {
    133.                 uma = BetterCameraControl.FindTransform(transform, gender).gameObject;
    134.                 BipedReferences.AutoDetectReferences(ref references, uma.transform, BipedReferences.AutoDetectParams.Default);
    135.             }
    136.         }
    137.  
    138.         void SetupIK()
    139.         {
    140.             /*// Set up BipedReferences
    141.             Transform[] bones = new Transform[6];
    142.             bones[0] = BetterCameraControl.FindTransform(transform, "Spine");
    143.             bones[1] = BetterCameraControl.FindTransform(transform, "Spine1");
    144.             bones[2] = BetterCameraControl.FindTransform(transform, "RightShoulder");
    145.             bones[3] = BetterCameraControl.FindTransform(transform, "RightArm");
    146.             bones[4] = BetterCameraControl.FindTransform(transform, "RightForeArm");
    147.             bones[5] = BetterCameraControl.FindTransform(transform, "RightHand");
    148.  
    149.              Transform[] lookatbones = new Transform[2];
    150.             lookatbones[0] = BetterCameraControl.FindTransform(transform, "Spine");
    151.             lookatbones[1] = BetterCameraControl.FindTransform(transform, "Spine1");
    152.  
    153.             // Set up ik
    154.             ik = uma.AddComponent<FullBodyBipedIK>();
    155.             ik.SetReferences(references, null);
    156.             ik.solver.SetLimbOrientations(BipedLimbOrientations.UMA);
    157.             ik.solver.OnPostUpdate += OnPostFBBIK;
    158.             ik.Disable();
    159.  
    160.             interactionSystem = uma.AddComponent<InteractionSystem>();
    161.          
    162.             // Set up Aim
    163.             aimIK = uma.AddComponent<AimIK>();
    164.             int i = 1;
    165.  
    166.             while (i < bones.Length)
    167.             {
    168.                 aimIK.solver.SetChain(bones, targetTransform);
    169.                 i++;
    170.             }
    171.             aimIK.solver.transform = targetTransform;
    172.             aimIK.Disable();
    173.  
    174.             // Set up LookAtIK
    175.             lookAtIK = uma.AddComponent<LookAtIK>();
    176.             lookAtIK.solver.headWeight = 1f;
    177.             lookAtIK.solver.head.transform = BetterCameraControl.FindTransform(transform, "Head");
    178.  
    179.          
    180.             lookAtIK.Disable();
    181.  
    182.         //    interactionSystem.lookAt.ik = lookAtIK;
    183.              * */
    184.         }
    185.      
    186.         #region Interaction
    187.  
    188.         /// <summary>
    189.         /// Process activation
    190.         /// </summary>
    191.         private void ProcessActivation()
    192.         {
    193.             if (controller.InNetwork && !controller.photonViewRef.isMine) return;
    194.  
    195.             if (InputManager.GetButton("Activate"))
    196.             {
    197.                 if (controller.InNetwork)
    198.                 {
    199.                     if (controller.photonViewRef.isMine)
    200.                         controller.photonViewRef.RPC("RemoteActivation", PhotonTargets.All, null);
    201.                 }
    202.                 else
    203.                     RemoteActivation();
    204.  
    205.                 /*
    206.                 // Check if there is an object to activate
    207.                 GameObject activationObject = GetComponent<PlayerUI>().LookedAtObject;
    208.               //  if (activationObject == null) return;
    209.               //  Debug.Log("AO");
    210.                 // Get triggers in range
    211.                 List<InteractionTrigger> triggers = interactionSystem.triggersInRange;
    212.                 Debug.Log(triggers.Count + " triggers found");
    213.  
    214.                 //// Find trigger that is being activated
    215.                 //for (int i = 0; i < triggers.Count; i++)
    216.                 //{
    217.                 //    Debug.Log(activationObject.name + " == " + triggers[i].gameObject.name);
    218.                 //    if (triggers[i].gameObject == activationObject)
    219.                 //    {
    220.                 //        // do nothing if the trigger is in interaction
    221.                 //        if (!interactionSystem.TriggerEffectorsReady(i)) return;
    222.  
    223.                 //        // Trigger is ok, activate
    224.                 //        interactionSystem.TriggerInteraction(i, false);
    225.                 //        currentWeapon = triggers[i].gameObject;
    226.                      
    227.                 //        //Casey added this 11/26/14
    228.                 //        Weapon weaponComp = currentWeapon.GetComponentInParent<Weapon>();
    229.                 //        weaponComp.enabled = true;
    230.                 //    }
    231.                 //}
    232.  
    233.                 int closestTrigger = interactionSystem.GetClosestTriggerIndex();
    234.  
    235.                 if (!interactionSystem.TriggerEffectorsReady(closestTrigger)) return;
    236.  
    237.                 // Trigger is ok, activate
    238.                 interactionSystem.TriggerInteraction(closestTrigger, false);
    239.                 currentWeapon = triggers[closestTrigger].gameObject;
    240.                 */
    241.             }
    242.         }
    243.  
    244.         /// <summary>
    245.         /// Activate given object, has to be in reach
    246.         /// </summary>
    247.         /// <param name="objectName"></param>
    248.         public void RemoteActivation()
    249.         {
    250.         //    GameObject activationObject = GetComponent<PlayerUI>().LookedAtObject;
    251.             List<InteractionTrigger> triggers = interactionSystem.triggersInRange;
    252.             Debug.Log(triggers.Count + " triggers found");
    253.  
    254.             int closestTrigger = interactionSystem.GetClosestTriggerIndex();
    255.  
    256.             if (!interactionSystem.TriggerEffectorsReady(closestTrigger)) return;
    257.  
    258.             // Trigger is ok, activate
    259.             interactionSystem.TriggerInteraction(closestTrigger, false);
    260.             triggers[closestTrigger].GetComponentInParent<NN.Gameplay.InteractableObject>().Activate(transform);
    261.         }
    262.  
    263.         /// <summary>
    264.         /// Sets the position of the aim target to the given Vector3
    265.         /// </summary>
    266.         /// <param name="pos"></param>
    267.         public void SetTargetPosition(Vector3 pos)
    268.         {
    269.             SetTargetPosition(pos.x, pos.y, pos.z);
    270.         }
    271.  
    272.         /// <summary>
    273.         /// Sets the target position of the aim target to xthe given x, y, z
    274.         /// </summary>
    275.         /// <param name="x"></param>
    276.         /// <param name="y"></param>
    277.         /// <param name="z"></param>
    278.         public void SetTargetPosition(float x, float y, float z)
    279.         {
    280.             targetPosition = new Vector3(x, y, z);
    281.         }
    282.  
    283.         /// <summary>
    284.         /// Toggles Aim On/Off
    285.         /// </summary>
    286.         public void ToggleAim()
    287.         {
    288.             ToggleAim(!Aiming);
    289.         }
    290.  
    291.         /// <summary>
    292.         /// Toggles aim to the given boolean
    293.         /// </summary>
    294.         /// <param name="on"></param>
    295.         public void ToggleAim(bool on)
    296.         {
    297.             if (currentWeapon == null) return;
    298.  
    299.             if (on)
    300.             {
    301.                 Aiming = true;
    302.                 aimIK.solver.transform = currentWeapon.transform;
    303.             }
    304.             else
    305.             {
    306.                 Aiming = false;
    307.                 LeftHand.positionWeight = 0f;
    308.                 RightHand.positionWeight = 0f;
    309.             }
    310.             transform.GetComponentInChildren<Animator>().SetBool("Alert", Aiming);
    311.         }
    312.         #endregion
    313.     }
    314. }
    315.  
    I fixed it by putting my FBBIK on the Parent GameObject with my InteractionController.

    Code (CSharp):
    1.  
    2. if (UseIK)
    3.             {
    4.                 uma = BetterCameraControl.FindTransform(transform, gender).gameObject;
    5.                 BipedReferences.AutoDetectReferences(ref references, uma.transform, BipedReferences.AutoDetectParams.Default);
    6.             }
    7.                         // Set up ik
    8.             ik = gameObject.AddComponent<FullBodyBipedIK>();
    9.             ik.SetReferences(references, null);
    10.             ik.solver.SetLimbOrientations(BipedLimbOrientations.UMA);
    11.             ik.solver.OnPostUpdate += OnPostFBBIK;
    12.             ik.Disable();
    It must be because my setup is slightly different from UMACrowd's heirarchy. My actual UMA isn't the parent but is a child of a GameObject. So FullBodyBiped has to go on the parent objectm not the one with the animator. Is that right?
     
    Last edited: Mar 31, 2015
  40. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    FBBIK should be on the game object with the Animator. It doesn't absolutely need to be, but it's safer. It can use the Animator to fill in the references if its a Humanoid and if FBBIK can't do it on it's own. It might be that FBBIK fails to fill in the references correctly and so fails to initiate. Currently FBBIK prefers it's own auto-detection over the Humanoid's, but I'm planning to change that, because the latter is pre-set and therefore never fails.
     
  41. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    327
    Hi Partel Lang,

    When you release the next version that support for Unity 5 ? I am using Unity 5, so i can not use Final IK version beta 5.0.
     
  42. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi!

    I don't understand...
    The current version is supported by Unity5.
    I have uploaded two versions of FinalIK 0.5. If you import with Unity 5, you'll get the Unity5 version, if with Unity 4, you'll get the Unity4 version.
    What kind of errors do you get?
     
  43. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Ah thanks Partel. I was putting it on the parent GameObject because for some reason I can't add it at runtime to the DynamiAvatar with the Animator on it. This sounds like a UMA problem so I'm in touch with them.
     
  44. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    327
    Hi,
    This is my error and change log version file. Or may i wrong version ?



     
  45. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Hi Partel. I fixed my problem and just wanted to share in case it helps someone else. When I'd generate my uma then do Add component and add my FBBIK script it loaded everything fine, no errors. so I figured there was something about the order the references being looked for before the uma was fully generated, even though i was using a callback. I changed my SetupIK() to

    Code (CSharp):
    1. IEnumerator SetupIK(){
    2. ...
    3. yield return new WaitForSeconds(5f);
    4.             BipedReferences.AutoDetectReferences(ref references, uma.transform, BipedReferences.AutoDetectParams.Default);
    then in
    Code (CSharp):
    1. Start()
    2. {
    3.  
    4.             if (references == null) { StartCoroutine("SetupIK"); }
    5. }
    6.  
    No idea why it had to be done this way.

    EDIT:
    I'm using the DeathToScriptableObjects branch of UMA2, there are many branches but this is the newest one and the one that's closest to release. I tried the UMA2 master and didn't have this problem. I messaged the UMA guys.
     
    Last edited: Apr 2, 2015
    Partel-Lang likes this.
  46. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Weird, I just downloaded the latest Unity (5.0.1), imported the package and had no errors like that.
    Maybe you have previously downloaded FinalIK 0.5 with Unity4 and it's stored somewhere so when you click Import from the download manager, it imports the Unity4 version even if you are in Unity5? Did you try downloading again from the download manager?

    Anyway those errors are because of changes in the API between Unity4 and Unity5, but they should be automatically fixed when it offers you to automatically convert the API.
    Actually there are no other notable differences between the Unity4 and Unity5 versions of Final IK. I basically just let Unity convert the API for me and submitted it just like that.

    Pärtel
     
  47. truffle_shuffle

    truffle_shuffle

    Joined:
    Dec 30, 2014
    Posts:
    16
    Partel, one of your scenes shows "pinning" the ragdoll to the animated model. I can't quite figure out how to pin the entire ragdoll to the model so I can achieve something like you show in this video
    . Can you point me in the right direction? Sorry if this is a dumb question, I've been researching all day and still haven't figured out how to do this.

    I want to ultimately make something along the lines of Gang Beasts
     
  48. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    140
    It's two fully seperate solutions. What you'd be looking for is more along the lines of Animfollow or PBC (both by the same creator). Although Partel did mention he'd work on his own solution some point after Final IK.
     
  49. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi, what Ragoo said.
    The ragdoll thing was not made with Final IK (as stated in the video), it is another solution I am still working on..

    Cheers,
    Pärtel
     
  50. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Hey forgive if this has been answered on this thread but can we use FinalIK to get IK at design time to use it to bake into animations to make the animation process easier?

    If so, what's the best method to do so?

    Using non skinned voxel characters but they still have 3 joint arms and legs.



    -Actually seems like the EffectorAnimator thing might help? I saw the youtube of it being a WIP a year ago. Is this working now? I dont see it in my asset.


    btw this is a pic of my rig. You can see that the meshes are just children (0,0,0 local pos) of the "bone" transforms (all set up in Unity). And I just keyframe animate the bone transforms in Unity dope sheet right now. This works fine, but I think legs/arms would be easier to animate with IK.




    Appreciated!
     
    Last edited: Apr 9, 2015