Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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. Yokil

    Yokil

    Joined:
    Sep 9, 2012
    Posts:
    26
    Thanks again.
     
  2. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Hi Patel. Really enjoying FinalK. I'm having trouble getting Objects placed in the characters hand correctly. It's always joining at the wrist, and always oriented the wrong way. I'm testing using the Trigger demo scene and my weapon seems to be setup exactly the same as the one in the demo. I've provided some screenshots

    Capture.PNG inspector.PNG
     
  3. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,077
    What a great system. I just purchased tonight and was experimenting with the aim of adding a driver for my boat. While perusing YouTube for tutorials, I saw there was a driver rig already included as a sample! It took all of twenty minutes to get it dropped into my speed boat simulator and working beautifully!

    Easily the best $90 I ever spent on the Asset Store. Thanks for the great work. I'd have paid more for it!

     
    WendelinReich likes this.
  4. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, are you sure the Effector Type of the InteractionTarget is RightHand? Because if the InteractionObject does not find an InteractionTarget parented to it, that matches the type of the interacting effector, it will use the Transform of the InteractionObject itself as the target, which is what this screenshot looks like.

    Hey, looking great and I am very glad you have found the package useful! :)

    Now if you want to take this further, you can make the seat a kinematic rigidbody, add another rigidbody above it, connect them with a spring joint that has some spring and damper, so it looks like an inverse pendulum. Then you can parent the shoulder effector targets to that pendulum and have the character swing about a bit when the boat turns. :)

    In theory at least....

    Cheers
    Pärtel
     
  5. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,077
    I'm playing around with Full Body Biped IK and am wondering if there is a way to get more precise control of the eyes. Say in a separate pass after the solver has computed all the matrices, perhaps the eyes could be done last so their matrices can just be set directly in world coords? I tried doing a transform.LookAt on an eye directly which almost works (also making sure my script execution comes after yours, not sure if it matters or if that's just an initial execution time thing), but it's not quite right.

    If not, that might be an idea for you: Do all the eyes last and just point them directly at whatever the target object is within some constraints of rotation. Maybe this might go against your whole design and idea behind it all, don't know. Just thought I'd throw that out there anyway. :) Then again, there's probably already a way to do it in your system!

    Great package, I can't stop playing with it. :)

    EDIT: I'm using Look At IK, by the way.
     
    Last edited: Oct 30, 2014
  6. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    Yes there is, Pärtel outsmarted you (and me before)! You want the eye bones aligned with the axis from them to a target, which is something you wouldn't use IK for, you'd just set each eye's transform.rotation directly. So the question is when you can do that. Answer: hook into solver.OnPostUpdate (explained here and here). Easy as pie.
     
    Partel-Lang and Todd-Wasson like this.
  7. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,077
    Great answer, thanks.
     
  8. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Thanks, Wendelin, for the help! :)

    Also, I wanted to add that if you wish to rotate the eyes, there is a helpful function in the package for making sure the eyes won't turn too far when the target is behind the head. Its RootMotion.V3Tools.ClampDirection().
    It clamps the range of a direction the same way AimIK and LookAtIK does, using clamp weight.

    Here's a bit of code that you can use for the eyes:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class EyeRotator : MonoBehaviour {
    5.  
    6.     [System.Serializable]
    7.     public class Eye {
    8.         public Transform transform;
    9.         public Vector3 forwardAxis = Vector3.forward;
    10.  
    11.         [HideInInspector] public Quaternion defaultLocalRotation;
    12.     }
    13.  
    14.     public Transform lookAtTarget;
    15.     [Range(0f, 1f)] public float lookAtWeight = 1f;
    16.     public Transform head;
    17.     public Vector3 headForwardAxis = Vector3.forward;
    18.     public Eye[] eyes;
    19.     [Range(0f, 1f)] public float clampWeight = 0.5f;
    20.     [Range(0, 2)] public int clampSmoothing = 1;
    21.     public bool eyesAnimated;
    22.  
    23.     void Start() {
    24.         foreach (Eye eye in eyes) {
    25.             eye.defaultLocalRotation = eye.transform.localRotation;
    26.         }
    27.     }
    28.  
    29.     void LateUpdate() {
    30.         if (lookAtWeight <= 0f) return;
    31.  
    32.         foreach (Eye eye in eyes) {
    33.             if (!eyesAnimated) eye.transform.localRotation = eye.defaultLocalRotation;
    34.  
    35.             Vector3 direction = lookAtTarget.position - eye.transform.position;
    36.             Vector3 headForward = head.rotation * headForwardAxis;
    37.  
    38.             bool clamped = false;
    39.             direction = RootMotion.V3Tools.ClampDirection(direction, headForward, clampWeight, clampSmoothing, out clamped);
    40.  
    41.             Quaternion fromToRotation = Quaternion.FromToRotation(eye.transform.rotation * eye.forwardAxis, direction);
    42.             eye.transform.rotation = Quaternion.Lerp(Quaternion.identity, fromToRotation, lookAtWeight) * eye.transform.rotation;
    43.         }
    44.     }
    45. }
    46.  
    If you set it to the last position in the Script Execution Order, it will execute after all IK components.

    Cheers,
    Pärtel
     
    Todd-Wasson and WendelinReich like this.
  9. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Is it possible to have multiple Interaction Targets on an object? I wanted to setup my fun with various interaction targets (handle, clip, chamber, hammer) and then do TriggerInteraction() or StartInteraction() to reposition the hand on different parts of the gun.
     
  10. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    You'd be better off using a single InteractionTarget and just moving/animating/interpolating that target between various poses. So you make a copy of the InteractionTarget transform and pose it to another location relative to the gun, get rid of the InteractionTarget comp on the copy and then you can just write target.localPosition = Vector3.Lerp(handlePosition, clipPosition, clipWeight); and same for the localRotation.

    Pärtel
     
  11. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Thanks Partel!
     
  12. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    416
    Partel,

    Using Grounder FBBIK and Grounder Quardruped, do have any ideas of how I might have my player character walk/run on a slippery surface like ice and have the animation adjust somewhat realistically to a slippery surface.

    I am currently using Grounder FBBIK and Grounder Quadruped during runtime to make my character run back and forth on a balance beam in both upright (grounder FBBIK) and a prone (grounder quad) crawling positions depending upon the angle of the tilting beam. I introduce an occasional snow storm and rain storm and thought it would be very cool to have the character's feet slipping on the surface as he is running, walking and crawling.

    The third person character controller provided by Unity that you also use in your grounder demo has settings you can adjust for Ground Sticky Effect and Platform Friction. But these options only adjust the rigidbody velocity and have no effect on the animation. (And the Ground Sticky Effect setting only provides a somewhat unrealistic velocity acceleration over time). It occurred to me that perhaps Final IK and your grounder system might be the solution.

    I noted in a previous post that someone had asked about wall running. I was amazed that in short order, you had a solution. So I thought I would present this challenge to see if you have any ideas.

    I appreciate any thoughts you might have.

    Allan
     
    Last edited: Oct 31, 2014
  13. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Sorry Partel I just wanted to clarify, this approach you mentioned won't allow me to use handposer correct?
     
  14. OrdinaryDev83

    OrdinaryDev83

    Joined:
    May 8, 2014
    Posts:
    23
    Hello guys, i'm new in Final IK and i want to create an FPS using "Aim" but i don't know how to set the Aim target, can you help me?(if you've a script in C# or a something) picture:
    Thank in advance guys, Bryckout :cool:
     
  15. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    138
    Check the documentation at: http://www.root-motion.com/finalikdox/html/page1.html

    It has various references as to how you can change the aim target.

    Code (CSharp):
    1. Changing the aiming target:
    2.  
    3. public AimIK aimIK;
    4. void LateUpdate () {
    5.     aimIK.solver.IKPosition = something;
    6. }
    Or

    Code (CSharp):
    1. public AimIK aimIK;
    2. void LateUpdate () {
    3.     aimIK.solver.transform = something;
    4.     aimIK.solver.axis = localAxisOfTheTransformToAimAtTheTarget;
    5. }
    You can also do it in the inspector:

    upload_2014-11-1_17-43-28.png
     
    Partel-Lang likes this.
  16. OrdinaryDev83

    OrdinaryDev83

    Joined:
    May 8, 2014
    Posts:
    23
    I have THIS in the inspector not your!
    Sans titre.png
     
  17. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    Hmmm - are you using the latest version of the Final IK beta (v. 0.41)?

    By the way, you can also set the aim target via code (via the .target member of the AimIK component). It's explained in the page linked to by Ragoo.
     
    Partel-Lang likes this.
  18. OrdinaryDev83

    OrdinaryDev83

    Joined:
    May 8, 2014
    Posts:
    23
    Okay, thank you for your help guys :p but can you give me the exact code for changing the target?
    I'm a noob in the CSharp, i prefer Javascript!:D
     
    Last edited: Nov 1, 2014
  19. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Just download the latest version.
     
  20. alexfeature

    alexfeature

    Joined:
    Apr 1, 2010
    Posts:
    132
    Got this last night! Mind blown....pixels everywhere.
     
  21. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, Allan,

    I can't think of a solution that would just solve this, but I have a few ideas for you.
    First, change the speed of the locomotion animation faster so it seems like there is not much friction. Then you can try to play around with FBBIK effector positionOffsets. You can use them to raise the arms to the side and bend the spine a bit as if the character was trying to maintain balance. Also, take a look at the "Inertia" and "Amplifier" demo scenes, perhaps they can be useful for the illusion and changing the look of the animation as well. It really depends on the animations that you have.

    Yes I forgot about the poser, sorry. But you can also do the posing easiest by animating the poser target. Actually thinking about it, why don't you create an Animator for the hand target and use the Animation Window to animate it's position and the pose of the fingers from state to state. Then you can use Mecanim to build a transition system or just use CrossFade to switch between static poses. It would rid of you from the necessity of writing code for it as well, plus you will have the ability to animate reloading, scope adjusting or whatever you need.. :)

    Hi,

    If you wish to use Javascript, you should first:

    1. create a folder at Assets/Plugins, copy the entire RootMotion package there
    2. create a folder at Assets/Editor
    3. go through all the subfolders of the RootMotion package except "_DEMOS" and move all scripts under the folders named "Editor" to the newly created Assets/Editor. When the console stops giving new error messages, you'll know you are done.

    Then you can change the AimIK target position by:
    Code (JavaScript):
    1. import RootMotion.FinalIK;
    2.  
    3. #pragma strict
    4.  
    5. var target: Transform;
    6. var ik: AimIK;
    7.  
    8. function Update () {
    9.     ik.solver.IKPosition = target.position;
    10. }
    Great!
    Thanks for the purchase and good luck with you game! :)

    Cheers,
    Pärtel
     
  22. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Thanks Partel that sounds like a good idea!
     
  23. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    Hi Pärtel, I have a small feature request for FBBIK! :)

    Could you give us away to turn off 'twist' (or 'roll') on each of the two bones forming elbow and knee joints? I understand why you always have it switched on: normally, a human knee/elbow is very (though not entirely) stiff on its local roll axis, so if the bend goal is moved (like in your driving rig sample scene), the two bones (femur/tibia and humerus/radius) should be rolled. This gives the impression that moving the bend goal rotates the entire limb.

    The thing is, in humans and animals, anatomically speaking the single DOF of the knee/elbow is not precisely orthogonal to the plane formed by the three joints. This is reflected in my dog rig, so when the rig is in an animated pose where elbow/knee are almost straight, the angle between the free axis and the plane can be completely off, and FBBIK tries to rotate the joints to a degree where it looks bad.

    Right now, 'Maintain hand/foot rotation' is available in FBBIK, and what I'm requesting would be something similar for knee/elbow, or simply an on/off switch. Would that be possible?

    By the way, if you're interested, I'm improvising a bit with my use of FBBIK for a quadruped. The problem is, most quadrupeds don't stand on their feet but on their toes, which means that FBBIK has to be set up so that 'elbow' actually refers to the 'hand' joint. This isnt perfect but works better than nothing, because unlike a human, a dog (horse etc.) is less flexible on the 'hand' (the radius/carpus joint). I'm trying to use FBBIK to create a semi-procedural idle loop, and right now it looks like it works...
     
  24. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Hi Partel!

    I have problems with my characters and hand placement. The models are created with fuse and rigged by mixamo autorig!

    I want a simple hand placing and i've used all solvers with the same problems. If i use limb ik i can get the better results, but not good enough. Some times the arm forearm or shoulder are twisted. Is ther any known problem with this? If i use full body ik, or biped ik, one arm bends in one way and the oder is always twisted even if i use the same parameters... I don't have the computer now, but i can send you some pics with the setup.

    Cheers!
     
  25. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, Wendelin,

    I made a little script for you.. It fixes the roll rotation of the elbow/knee relative to the upper arm/thigh, if thats what you meant. :)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. [RequireComponent(typeof(FullBodyBipedIK))]
    6. public class FixLimbRoll : MonoBehaviour {
    7.  
    8.     // Fixes the roll rotation of the second bone relative to the first bone of a limb
    9.     [System.Serializable]
    10.     public class Limb {
    11.         public FullBodyBipedChain chain;
    12.         [Range(0f, 1f)] public float fixWeight = 1f;
    13.  
    14.         private Vector3 axis;
    15.         private Quaternion defaultLocalRotation;
    16.         private Transform firstBone, secondBone, thirdBone;
    17.         private IKSolverFullBodyBiped solver;
    18.  
    19.         public void Initiate(IKSolverFullBodyBiped solver) {
    20.             this.solver = solver;
    21.  
    22.             // Some quick references
    23.             firstBone = solver.GetChain(chain).nodes[0].transform;
    24.             secondBone = solver.GetChain(chain).nodes[1].transform;
    25.             thirdBone = solver.GetChain(chain).nodes[2].transform;
    26.  
    27.             // Remember the default rotations of the elbow knee bones relative to the first bones of the respecitve limbs
    28.             defaultLocalRotation = Quaternion.Inverse(firstBone.rotation) * secondBone.rotation; // Not using localRotation because there might be twist bones in between
    29.         }
    30.  
    31.         public void OnPreRead(IKSolverFullBodyBiped solver) {
    32.             if (fixWeight <= 0f) return;
    33.             if (this.solver == null || firstBone != solver.GetChain(chain).nodes[0].transform) Initiate(solver); // Something has changed, reinitiate
    34.  
    35.             // Read the local axes of the elbow/knee bones towards the end bones
    36.             axis = Quaternion.Inverse(secondBone.rotation) * (thirdBone.position - secondBone.position);
    37.         }
    38.  
    39.         public void OnPostUpdate() {
    40.             if (fixWeight <= 0f) return;
    41.  
    42.             // Rotate to default local rotation, which fixes the roll, then swing back to the solved direction
    43.             Vector3 direction = secondBone.rotation * axis;
    44.            
    45.             Quaternion r = firstBone.rotation * defaultLocalRotation;
    46.             r = Quaternion.FromToRotation(r * axis, direction) * r;
    47.            
    48.             if (fixWeight >= 1f) {
    49.                 secondBone.rotation = r;
    50.             } else {
    51.                 secondBone.rotation = Quaternion.Lerp(secondBone.rotation, r, fixWeight * solver.IKPositionWeight);
    52.             }
    53.         }
    54.     }
    55.  
    56.     public Limb[] limbs;
    57.  
    58.     private FullBodyBipedIK ik;
    59.  
    60.     void Start() {
    61.         ik = GetComponent<FullBodyBipedIK>();
    62.  
    63.         foreach (Limb limb in limbs) limb.Initiate(ik.solver);
    64.  
    65.         ik.solver.OnPreRead += OnPreRead;
    66.         ik.solver.OnPostUpdate += OnPostUpdate;
    67.     }
    68.  
    69.     // Called by FBBIK each frame before reading the pose of the character
    70.     private void OnPreRead() {
    71.         if (!enabled) return;
    72.        
    73.         foreach (Limb limb in limbs) limb.OnPreRead(ik.solver);
    74.     }
    75.  
    76.     // Called by FBBIK each frame after finished updating
    77.     private void OnPostUpdate() {
    78.         if (!enabled) return;
    79.        
    80.         foreach (Limb limb in limbs) limb.OnPostUpdate();
    81.     }
    82.  
    83.     // Clean up the delegates
    84.     void OnDestroy() {
    85.         if (ik != null) {
    86.             ik.solver.OnPreRead -= OnPreRead;
    87.             ik.solver.OnPostUpdate -= OnPostUpdate;
    88.         }
    89.     }
    90. }
    91.  
    Hi, Danirey,

    Have you seen this video (from 1:50)?
    Mixamo rigs have their arms and feet completely stretched out, which means FBBIK and LimbIK cant calculate the normal of the bend plane. Just rotate the elbows and knees, so the limbs would be bent slightly in their natural bending directions (indicated by the little blue arrows on the armature).

    Pärtel
     
  26. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Oh!! I didn't... It is the only one i didn't check. Thanks a lot, as always! :D
     
  27. choquerg

    choquerg

    Joined:
    Nov 4, 2014
    Posts:
    3
    Hi, for what I've seen, your plugin seems pretty neat.

    I have a little question though , I work on a scene containing a biped model, on wich I've attached a Full Body Biped IK component. It has 5 effectors set, one on the body, and the final effectors of each limb. I've already check and corrected some of the the automatically detected references and the test I've run so far by directly modifing the effectors targets transforms seems to behave rather correctly.

    But , although the effectors start positions & orientations are strictly equal to their associated bones positions & orientations, I still observe an slight offset that affect the body when i launch the runtime mode, and I unable to tell from where it could be induced, as there is nothing to be solve.

    I have also weight out all the effectors, and this offset still happen , an ever slighter one, but still. Is it due to the mapping phase with the low resolution skeleton or am i missing something ?
     
    Last edited: Nov 4, 2014
  28. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi,
    Its difficult to say, could you send me some screenshots and/or the character model to support@root-motion.com?

    Cheers,
    Pärtel
     
  29. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    138
    Hi Partel,

    Is there a built-in way to set the Lerping speed for individual FBBIK components? I've found that there can be quite a bit of jitter (logically), which should be removeable using a smoothing speed or Tween.
     
  30. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, Ragoo,
    I didn't quite understand, lerping speed of what exactly and what jitter?

    By the way, talking about interpolation, one of the hidden secret features included in the package is a class called "Interp" in the RootMotion namespace. You can use it like so:

    Code (CSharp):
    1. float smooth = Interp.Float(linear, InterpolationMode.InOutSine);
    2.  
    ...where linear is a floating point value from 0 to 1 and InterpolationMode is the smoothing type.
    There are 27 different interpolation modes to choose from and they are most useful if you don't want to work with the annoying AnimationCurve editor too much.

    Pärtel
     
  31. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    138
    Hi Partel,

    Thanks for the reply.

    Great! I'll have a look at those. They should prove to be most handy in getting the desired smoothing behaviours.

    In my case, I'm using a number of your components simultaneously: AimIK, LookIK, MotionAbsorb etc.

    Now AimIK allows you to set the target, but in most cases I'd like the component to follow the target smoothly (rather than me maniuplating the aim target's position smoothly). With Aim IK, when at extreme angles (e.g. looking at the back) the solver has to rotate from one horizontal extreme to the other (due to constraints), which is executed instantly (if I'm not mistaken).

    Same with MotionAbsorb's effector updates, which I sometimes need to smoothly lerp to their new positions. With both components, in extreme cases the solver folds in on itself which causes jitter - which I think can be avoided if a smoothing value can be set.

    The question was whether there is a built-in way to smoothly set effector positions or smoothly update other FBBIK components - as I'm assuming a built-in method would be most efficient.


    Thanks,

    Khaya
     
  32. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    When interpolating the AimIK target, its best to use Vector3.Slerp to rotate the direction rather than Lerp to the target directly. That is because for instance when lerping from left to right, it might at some point get too close to the character, causing unwanted effects as you have mentioned.

    I made a small script, attach it to a gameobject that you want AimIK to smoothly interpolate towards:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. public class AimTargetSmooth : MonoBehaviour {
    6.  
    7.     [Tooltip("The AimIK component.")]
    8.     public AimIK aim;
    9.     [Tooltip("The speed of continuously slerping the aiming direction towards the target.")]
    10.     public float slerpSpeed = 5f;
    11.     [Tooltip("The speed of rotating the aiming direction towards the target in addition to slerping for a more snappy behaviour.")]
    12.     public float rotateTowardsMaxRadians = 2f;
    13.     [Tooltip("The speed of moving the aiming direction magnitude towards the target in addition to slerping for a more snappy behaviour.")]
    14.     public float rotateTowardsMaxMagnitude = 2f;
    15.     [Tooltip("Min aiming distance to avoid the solver rolling in on itself.")]
    16.     public float minDistance = 1f;
    17.  
    18.     void LateUpdate() {
    19.        aim.solver.target = null;
    20.  
    21.         Vector3 pivot = aim.solver.bones[0].transform.position;
    22.         Vector3 direction = aim.solver.IKPosition - pivot;
    23.         Vector3 directionTarget = transform.position - pivot;
    24.  
    25.         // Slerp
    26.         if (slerpSpeed > 0f) direction = Vector3.Slerp(direction, directionTarget, Time.deltaTime * slerpSpeed);
    27.  
    28.         // RotateTowards to snap to the target
    29.         if (rotateTowardsMaxRadians > 0f && rotateTowardsMaxMagnitude > 0f) {
    30.             direction = Vector3.RotateTowards(direction, directionTarget, Time.deltaTime * rotateTowardsMaxRadians, Time.deltaTime * rotateTowardsMaxMagnitude);
    31.         }
    32.  
    33.         // Min aiming distance to avoid the solver rolling in on itself
    34.         if (minDistance > 0f && direction.magnitude < minDistance) direction = direction.normalized * minDistance;
    35.  
    36.         // Assign the rotated direction towards the target to AimIK
    37.         aim.solver.IKPosition = pivot + direction;
    38.     }
    39. }
    40.  
    I don't think there is a good way to build this kind of stuff in to the IK solver itself, there is no way to define the "right" behaviour from the "wrong" as there are so many ways to smooth things and besides that, it also depends on the type of chain and the situation that you are trying to solve.

    Cheers,
    Pärtel
     
  33. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    Thanks for your help! I struggled a bit with this script because it turned out not work, barely affecting the three limb bones at all. I figured out why, I think: it doesn't change the roll of the first bone (the one corresponding to the thigh/upper arm) but only that of the second relative to the first. Thus, because the relative twist between second and first remains almost unaffected by LimbIK, the script ends up making no difference. At first I thought I could just correct the script by making a similar change to the first bone, but that messes up the solution for the second bone, because that one is a child of the first.

    In the end, I decided to use the plumbing from your script but with a different, simpler mathematical approach, not elegant but functional. The following script uses the fact that twist/roll is usually (if your character's rig isn't very strange) on one of the three principal local axes. So we can just check in OnPostUpdate() how much the first bone was rotated on that axis by LimbIK, and fix roll for both first and second bone. Since my rigs (from a Blender-to-Unity pipeline) always have bone-roll on local "-X", I hardcoded that into the script. So if anyone wants to use this they have change that or find a more general approach!

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using RootMotion.FinalIK;
    4.  
    5. using MischiefAI.UnityServer;
    6.  
    7. [RequireComponent(typeof(FullBodyBipedIK))]
    8. public class FixLimbRoll : MonoBehaviour
    9. {
    10.     // Fixes the roll rotation of the second bone relative to the first bone of a limb
    11.     [System.Serializable]
    12.     public class Limb
    13.     {
    14.         public FullBodyBipedChain chain;
    15.         [Range(0f, 1f)] public float fixWeight = 1f;
    16.  
    17.         private Transform firstBone, secondBone, thirdBone;
    18.         private Quaternion firstBonePreRead;
    19.         private IKSolverFullBodyBiped solver;
    20.  
    21.         public void Initiate(IKSolverFullBodyBiped solver)
    22.         {
    23.             this.solver = solver;
    24.  
    25.             // Some quick references
    26.             firstBone = solver.GetChain(chain).nodes[0].transform;
    27.             secondBone = solver.GetChain(chain).nodes[1].transform;
    28.             thirdBone = solver.GetChain(chain).nodes[2].transform;
    29.         }
    30.  
    31.         public void OnPreRead(IKSolverFullBodyBiped solver)
    32.         {
    33.             if (fixWeight <= 0f) return;
    34.             if (this.solver == null || firstBone != solver.GetChain(chain).nodes[0].transform) Initiate(solver); // Something has changed, reinitiate
    35.  
    36.             firstBonePreRead = firstBone.rotation;
    37.         }
    38.  
    39.         public void OnPostUpdate()
    40.         {
    41.             if (fixWeight <= 0f) return;
    42.  
    43.             Quaternion secondBoneRotation = secondBone.rotation; // remember global rotation of second bone before correction of its parent
    44.             Quaternion thirdBoneRotation = thirdBone.rotation; // ditto for third
    45.  
    46.             // determine roll angle we need to correct; assumption is that bone rolls on local -x axis
    47.             float angle = -firstBonePreRead.RelativeRotation(firstBone.rotation).eulerAngles.x;
    48.             Quaternion rollCorrection = Quaternion.Euler(new Vector3(angle, 0, 0));
    49.  
    50.             if (fixWeight >= 1f)
    51.             {
    52.                 firstBone.rotation *= rollCorrection;
    53.                 secondBone.rotation = secondBoneRotation * rollCorrection;
    54.                 thirdBone.rotation = thirdBoneRotation; // third bone is held still
    55.             }
    56.             else
    57.             {
    58.                 firstBone.rotation = Quaternion.Lerp(firstBone.rotation, firstBone.rotation * rollCorrection, fixWeight * solver.IKPositionWeight);
    59.                 secondBone.rotation = Quaternion.Lerp(secondBoneRotation, secondBoneRotation * rollCorrection, fixWeight * solver.IKPositionWeight);
    60.                 thirdBone.rotation = thirdBoneRotation; // third bone is held still
    61.             }
    62.         }
    63.     }
    64.  
    65.     public Limb[] limbs;
    66.  
    67.     private FullBodyBipedIK ik;
    68.  
    69.     void Start()
    70.     {
    71.         ik = GetComponent<FullBodyBipedIK>();
    72.  
    73.         foreach (Limb limb in limbs) limb.Initiate(ik.solver);
    74.  
    75.         ik.solver.OnPreRead += OnPreRead;
    76.         ik.solver.OnPostUpdate += OnPostUpdate;
    77.     }
    78.  
    79.     // Called by FBBIK each frame before reading the pose of the character
    80.     private void OnPreRead()
    81.     {
    82.         if (!enabled) return;
    83.  
    84.         foreach (Limb limb in limbs) limb.OnPreRead(ik.solver);
    85.     }
    86.  
    87.     // Called by FBBIK each frame after finished updating
    88.     private void OnPostUpdate()
    89.     {
    90.         if (!enabled) return;
    91.  
    92.         foreach (Limb limb in limbs) limb.OnPostUpdate();
    93.     }
    94.  
    95.     // Clean up the delegates
    96.     void OnDestroy()
    97.     {
    98.         if (ik != null)
    99.         {
    100.             ik.solver.OnPreRead -= OnPreRead;
    101.             ik.solver.OnPostUpdate -= OnPostUpdate;
    102.         }
    103.     }
    104. }
    105.  
     
    louise_jumpship and Partel-Lang like this.
  34. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521

    Oh, seems like I misunderstood you, but I'm glad you got it working and thanks for sharing the code! :)

    Pärtel
     
  35. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    138
    As always, thanks! I'll work on making my own smoothing solution...
     
  36. NiKoMaKi

    NiKoMaKi

    Joined:
    Nov 8, 2014
    Posts:
    15
    Hi Partel. I have a request. I'd like to purchase Final IK but cannot because on the Unity Asset Store it says the asset pack requires Unity version 4.5.2 or higher. However, at the start of this thread you stated Unity 4.3 or higher is supported.
    Currently I have no option in using any version other than 4.3.7p3 (because of the target platform - a console). There has been talk that 5.0 will be supported in the near future, for the platform I am releasing for, but this is not definite and I need to progress in production immediately.
    Your program looks to fit exactly what I needed and am what I am needing to start on right now. So, is there any way to lower the requirements so I can purchase and download Final IK?

    I've sent an email to two of your addresses already, but since I haven't heard back yet, I thought I'd post here too about it (I understand it's been the weekend, so maybe it hasn't had a chance to get your attention).

    Thanks.
     
  37. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, and sorry for the delay.

    I answered your e-mail earlier today, but anyway, if anyone else is interested,
    I just installed Unity 4.3.4 and imported the latest FinalIK package to see if it works. To my surprise it imported without a problem. Only had to change line 44 in SolverManager.cs to:

    Code (CSharp):
    1. if (animator != null) return animator.animatePhysics
    because 4.3 didn't have the Animator.UpdateMode yet.
    Best Regards,
    Pärtel
     
  38. NiKoMaKi

    NiKoMaKi

    Joined:
    Nov 8, 2014
    Posts:
    15
    Thanks Partel. For some reason I didn't get a notice of your email.

    One thing though - I cannot buy your asset pack through the Unity Store when accessed through the Unity program. I do have an option to buy using the Store's website. I'm new to Unity, so I'm just wondering, can I download your asset pack even though the Store through the program is trying to not allow me to? I mean, if I purchase through the website, do you think it will then be available to me to download in my store account through the program?
     
  39. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    I have a very aggressive spam filter that labels some incoming mails with ***SPAM*** and that gets included when I forget to remove that and reply, so perhaps it ended up in your junk folder. :)

    Is the store not allowing you to download because of using old Unity? If that's so, you can download to an empty project using the latest Unity, then export the package and re-import with old Unity.

    Pärtel
     
  40. NiKoMaKi

    NiKoMaKi

    Joined:
    Nov 8, 2014
    Posts:
    15
    I was able to purchase it from Unity's website and it was then listed in the purchased assets list of my account. I've downloaded it, imported it, made the change you mentioned, and all seems well so far. I can run the demos fine (other than some shaders not working - but that's because of the version of unity I have).

    I'm looking forward to using Final IK. However, it's unfortunate to know my emails to you are deemed spam. In case of support emergencies, I guess I will post here to make sure you had gotten my email (if time passes with no response).

    Thanks!
     
  41. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    Hi Pärtel, I have a question about this code example of yours (from back in May). I've noticed that GrounderQuadruped also has a "solver" variable, so one could call m_GrounderQuadruped.solver.Update();

    So what's the correct way of combining FBBIK, GrounderQuadruped and (in my case) AimIK? Should I do as in your code but also call m_GrounderQuadruped.solver.Update(), or can that be ignored, or can that be used instead of updating each limb? In that case, should I disable m_GrounderQuadruped (which has no Disable() method)? If not, does it matter if the GrounderQuadruped component is en-/disabled in the Editor?

    Confused: Wendelin
     
  42. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    138
    How are you going to combine Full Body Biped IK with a Quadruped grounder? Assuming the quadruped will have all fours on the ground, that's going to affect the torso as well, meaning all components need to be called in the right sequence.

    The right sequence (I presume) would be:

    AIM > FBBIK > Grounder

    This would indeed require you to disable all components (set the bool "enabled" to false), by creating an IK Manager script that also calls the Update methods in the right sequence.
     
    Partel-Lang likes this.
  43. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    FBBIK and GrounderQuadruped can be combined, although its not ideal (Pärtel says he's working on a FullBodyGenericIK solution for Final IK 1.0, that'll probably be better). I only use the inner-body effectors (shoulder, thighs) to add a little procedural swaying etc to my dog.

    AimIK is only for the neck, so I let it solve after the grounder. But my question to Pärtel was not really about the sequence but about how I should treat GrounderQuadruped in the code. It's a confusing component - not really a solver, but a container of LimIK solvers. But then, how does it manage (correctly!) to align the body with the ground when the forelegs are higher/lower than hindlegs???
     
  44. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, Wendelin

    The Grounder components are different, because they are not solving any IK of their own, but calculating stuff and feeding the results into the IK solver(s) that they are affiliated with. The "solver" of all Grounder components is not an IK solver, but a Grounding solver, that calculates for an arbitrary number of legs and a single hub that they are connected to (like the pelvis). In the case of GrounderQuadruped, it has 2 Grounding solvers, one for the hindlegs and one for the forelegs. (I could make a GrounderCentipede following the same logic :)) The GrounderComponent updates both solvers and then rotates the spine of the dog according to the height offset between the 2 hubs. Thats how it aligns the body to the ground when the forelegs are higher/lower than the hindlegs. I agree the name "solver" can be easily confused with IK solvers, but I can't change that anymore without messing up your existing serialized Grounder components.

    The Grounders update automatically each time before and only if their IK solvers update. So if you are using GrounderFBBIK, it will update with the FBBIK solver. GrounderQuadruped updates before any of it's IK components update. They do so by registering to the OnPreUpdate delegate of the IK solvers.

    Pärtel
     
  45. WendelinReich

    WendelinReich

    Joined:
    Dec 22, 2011
    Posts:
    228
    OK, i c... and I take this to mean that I can safely ignore GrounderQuadruped, as in your example code. I just let the Limbs solve after the FBBIK. Cool, makes my life easier! Thanks for the reply, happy weekend everyone W
     
    Partel-Lang likes this.
  46. Faikus

    Faikus

    Joined:
    Jan 3, 2011
    Posts:
    229
    Thanks for the head effector! I have started to experiment with it. It works already quite well and I can do some fun dancing in the Rift + Hydra (see this short video I just recorded: https://dl.dropboxusercontent.com/u/341696/LetsDance.mp4 If you have a Rift and Hydra you can try this short experiment yourself here: http://tore-knabe.com/virtual-reality#LetsDance). As you can see at 2:50 in the video, I am trying to get the different head pecking movements to work, like here:
    . It doesn't seem to work though, the upper body "absorbs" my pecking. I tried to reduce the body weight of the head effector, but then strangely the lower body is levered and swept off the ground, feet dangling in the air. Any tips? But even in the current state it is awesome! :)
     
    Last edited: Nov 16, 2014
    Partel-Lang likes this.
  47. OnePxl

    OnePxl

    Joined:
    Aug 6, 2012
    Posts:
    307
    *Slow clap* This is so awesome! Well done!
     
    WendelinReich likes this.
  48. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,521
    Hi, Faikus, that is a super duper funky video! :D

    The reason why the body absorbs the pecking is that FBBIK (and the head effector) doesn't use any neck bones at all, there is no neck in the References of FBBIK. So the movement of the head is transferred to the shoulders 1:1. I'll try to come up with a solution for you though, hold on, might take a day or 2.
     
  49. Slonika

    Slonika

    Joined:
    Jun 15, 2014
    Posts:
    7
    Hello, i have some bug with FBBIK. It seems to rotate knee in opposite direction. What can i do to fix it?
     

    Attached Files:

  50. LudiKha

    LudiKha

    Joined:
    Feb 15, 2014
    Posts:
    138
    Before starting the scene, make sure the character it's applied to is set up properly. This means bending the limbs slightly in the direction they should be bent. Your model probably does not have a bend at the knee.
     
    Partel-Lang likes this.