Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    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. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Hi Partel,

    thanks for the response about the "holding torch" problem. You mention that you are reworking the learning materials. Could you share some ETA for this? I'm very interested since I think this is the right approach but is a bit hard to get over it.

    Thanks
     
  2. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Hi Partel,
    I was checking the InteractionTrigger scene. It's so cool. I love to see that player use left hand if is the one more natural or the right hand. It was a problem I was facing trying to do by my self. Another cool feature was that I convert the ball to prefab and all works ok with many balls. Great too :)

    The problems I see:

    a) If a mark the "Pause" check box, the pilot doesn't walk with the ball as I would expect so I can left in other place of the scene.

    b) Trying to use the prefab in my scene doesn't work as expected (normal as I must tweak the hands to use my model and more config), but the main problem is that there's too much complexity behind the curtains. Maybe some video tutorial would be very useful.

    But I think b) should be combined with a) since is a need to displace objects in the scene and this should be implemented taking into account that people would need different instances of the same object in the scene.

    I can see is possible but I need to read and learn more about this great asset since is not trivial to manage
     
  3. Recon03

    Recon03

    Joined:
    Aug 5, 2013
    Posts:
    845
    I will report it to Unity then... must be a bug on there end..
     
  4. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Hi! I have already started working on adding more video tutorials, I've already made 3 videos in the past few days.
    Im hearing you, the Interaction System needs to be next, so I'll try to make something before the weekend.

    Must be.. Anyway, if you have some feedback to share you might as well post it here or feedback@root-motion.com.

    Cheers,
    Pärtel
     
  5. Martin_H

    Martin_H

    Joined:
    Jul 11, 2015
    Posts:
    4,436
    @Pärtel: Thanks a lot for making new tutorial videos! I'll check 'em out when I start working with FinalIK. Could you maybe leave out the background music for the next videos please? It's not a problem for the text only videos that I can just mute, but when I try to listen to you talking it is distracting to have the music in the background. I'm sure at least some people are gonna agree with me on that. Thanks and keep up the great work!
     
  6. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Oh, just in case you haven't noticed, I do have a basics tutorial for the Interaction System, it's a bit outdated, but might help a bit..
     
  7. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Sure, I'll cut the music for the next ones. :)
     
    John-G and Martin_H like this.
  8. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Many Thanks Partel for taking this into account, your support is great!

    As I follow up trying to disect the Interaction Trigger demo scene I'm a bit stuck since it depends on several additional Scripts and a specific setup. For example, I must add the "UserControlsInteraction" Script, but this makes me add the "CharacterThirdPerson" Script... so I'd would ask you if is possible some rewrite or reimplementation to make it more like a generic component, since this would be killer to ease development and make it even more awesome.

    Thanks again Partel

    Carlos
     
  9. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    btw, I saw the new videos yesterday and suscribe to youtube channel. Great content for sure. Thanks!
    (and yes I saw and follow the basic outdated video, to get with the basics of the system, thanks!)
     
    Partel-Lang likes this.
  10. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    No you don't actually need that specific script, it is not a part of the system, just a demo script for learning purposes.
    You should use the code samples in there to make your own user controls, I cant foresee every possible scenario of using the triggers.
     
  11. ggrin

    ggrin

    Joined:
    May 20, 2013
    Posts:
    6
    We came up with real complex set up (had our reasons :) ) where the gun is a separate object parented to a ribcage (spine3) being controled by it's own (first person) animator. Now I see, that HandsOnProps is not enough to compensate all the offset. Do you have any suggestions besides changing hierarchy?

    I really appriciate your fast replys! Thank you!
     
  12. ggrin

    ggrin

    Joined:
    May 20, 2013
    Posts:
    6


    On the left: IK Target only
    On the right: + Bend Goal (one of the green spheres)

    Blue arrows look good to me but still, result that I had with LimbIK and Animation ModifierBend is much better (is close to the right pic). But I'm not sure if I can maintain Bend Goal Transform right for every animation, and it's look very complex for now.

    Let me know if you have any ideas or an advice. And thanks again :)
     
  13. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Are you using effector rotation and rotationWeight?
    If so, don't. :)
    Instead, just rotate the hand bone in LateUpdate to match the target and set "Maintain Hand Rot" to 1 in the FBBIK inspector. How does it look then?

    I'll get back to you about the other question, I'll think of something..
     
  14. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    When the gun is parented to the spine, it is not possible to tell where it will end up in the solving process, so there is no way to calculate the IK targets for the hands to be solved simultaneously. But you can add LimbIK components to both arms, and solve them to put the hands back after FBBIK is done. LimbIK is very fast so it should not be a big problem. You can use this code:

    Code (CSharp):
    1. public FullBodyBipedIK ik;
    2.     public LimbIK leftArm, rightArm;
    3.     public Transform gun;
    4.  
    5.     private Vector3 leftHandRelativePos, rightHandRelativePos;
    6.     private Quaternion leftHandRelativeRot, rightHandRelativeRot;
    7.  
    8.     void Start() {
    9.         // Register to get a call from FBBIK each time it is done updating
    10.         ik.solver.OnPostUpdate += AfterFBBIK;
    11.  
    12.         // Disable the LimbIK components
    13.         leftArm.Disable();
    14.         rightArm.Disable();
    15.     }
    16.  
    17.     void LateUpdate() {
    18.         // Remember the postition of the hands relative to the gun as animated
    19.         leftHandRelativePos = gun.InverseTransformPoint(ik.references.leftHand.position);
    20.         rightHandRelativePos = gun.InverseTransformPoint(ik.references.rightHand.position);
    21.  
    22.         // Remember the rotation of the hands relative to the gun as animated
    23.         leftHandRelativeRot = Quaternion.Inverse(gun.rotation) * ik.references.leftHand.rotation;
    24.         rightHandRelativeRot = Quaternion.Inverse(gun.rotation) * ik.references.rightHand.rotation;
    25.     }
    26.  
    27.     void AfterFBBIK() {
    28.         // Set hand IK target positions
    29.         leftArm.solver.IKPosition = gun.TransformPoint(leftHandRelativePos);
    30.         rightArm.solver.IKPosition = gun.TransformPoint(rightHandRelativePos);
    31.  
    32.         // Update the LimbIK solvers
    33.         leftArm.solver.Update();
    34.         rightArm.solver.Update();
    35.  
    36.         // Rotate the hand bones
    37.         ik.references.leftHand.rotation = gun.rotation * leftHandRelativeRot;
    38.         ik.references.rightHand.rotation = gun.rotation * rightHandRelativeRot;
    39.     }
     
    Last edited: Aug 28, 2015
  15. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    The first part of the Interaction System tutorial video series is up...
     
    carlosrovira likes this.
  16. Ron-Wilson

    Ron-Wilson

    Joined:
    Oct 2, 2012
    Posts:
    37
    Partel
    I just watched part one of interaction system tutorial and that is exactly what has been needed.......
    well done !
    Ron
     
    Partel-Lang likes this.
  17. Recon03

    Recon03

    Joined:
    Aug 5, 2013
    Posts:
    845
    I like doing it for others to see when buying it. Some people do not read forums before they buy.
     
  18. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Very useful this part one. Many Thanks for doing this. It's very needed to get the most of FINAL IK.
    Can't wait to see the next one.
    Thanks!
     
    Partel-Lang likes this.
  19. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    Hi, when 3d person character walk on terrain everything looks good but If I put a box instead legs starts shaking. even when it doesn't move.
     
  20. RFLG

    RFLG

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

    First of all, great work on V1.0! This is really a must-have when it comes to Unity components and it's great to see how it evolved since the beta.

    Now, I do have a question for you:

    -I've have setup a FBBIK which uses two effectors (one per hand) to control arm movement (inputs come from somewhere else) and it is working great. However, I would like to have some rotations on the wrist/forearm besides arm movement.

    I though about using the LimbIK component, my my problem is that all the movent comes in realtime (my input controls directly the two effectors), so basically the ideal solution would be for the effector to provide rotation along with movement. Is this possible with Final IK? If not, how would you approach this?

    Thank you for the time and for the help!
     
  21. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Hi! Check the layer of the box, is it the same as the terrain, is it included in the layers of the Grounder solver?

    Hi and thanks!

    Yes, first you can try setting effector.rotation to the controller's rotation and setting effector rotation weight to 1.
    It might be that the elbows behave different from what you need, so the other option would be to just rotate the hand bone to match the controller's rotation. If you set "Maintain Hand Rot" to 1 in the FBBIK Inspector for the arms. That will take care of rotating the wrists. For the elbows you can assign bend goals and set bend goal weight to something greater than 0.

    Cheers,
    Pärtel
     
  22. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    It's a default Unity box. I don't know why but when a box is big character shaking on it but after I make it small the issue will solve. Do you know why?
     
  23. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    would it be possible to make a screen capture of this "shaking" behaviour and send it to me support@root-motion.com?
     
  24. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    Sorry I can't record video for now but just go to Grounder demo and scale that green box a lot bigger (in X and Z axis). then you can see how it'll shaking.
     
  25. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    which green box? I tried scaling a bunch of them, did not see any shaking :S
     
  26. ksam2

    ksam2

    Joined:
    Apr 28, 2012
    Posts:
    1,079
    Here is the video. I just scaled that green box in X and Z axis.

     
  27. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Hey, thanks for the video, it is very helpful!
    I have made a test scenario, turns out it is a Unity bug/limitation with SpereCasting and CapsuleCasting. Apparently they fail against large colliders. If you switch Grounder quality to "Fastest" this problem will go away, because it will use Raycasting instead of CapsuleCasting. If you are also using the character controller from the grounder demo, you'll have to change line 59 in CharacterBase.cs to
    Code (CSharp):
    1. Physics.Raycast(ray, out h, airborneThreshold * 2f, groundLayers);
    I will look into it a bit more and perhaps make a bug report to Unity, although I'm afraid it's not a bug, but a floating point precision problem or something like that.
     
    hopeful and ksam2 like this.
  28. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Hi Partel,

    After checking your latest video on Interaction System basic, I'm heading on to Interaction Trigger Component. As you said and after reading I see it should be the solution. But, although in the scene demo there's many different movements, I think it needs something more. Let me explain:

    a) MOVE OBJECTS FROM ONE PLACE TO ANOTHER: Take a Box (Cube) and move it to another location in the scene (all samples interacts with objects, but all remains the same as interaction ends). How could this be done? I think there's all pieces of the puzzle around, but we need some example.

    I want to move a box in a puzzle game, or take a torch from one place and left in another place of the scene.

    b) PUSH/PULL OBJECTS FROM ONE PLACE TO ANOTHER: Like in Tomb Raider saga, when lara push a block or pull from a block.

    This learning material would be very useful since right now (with the demo sample) we can solve static object interactions (push button, open door, cigarret...), but the ball or weapon samples needs some more work since If I take the ball is to be able to left in another place...

    Thanks for listening Partel.

    Carlos
     
  29. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    Hey, I'm super impressed with this, setting up a ragdoll and transitioning from animation <--> ragdoll works wonderfully with the ragdoll utility! I'm wondering is there is a way to ragdoll only certain bones? For example, have a running animation like normal, but have one arm in ragdoll mode?

    I'm also curious if there is a simple way to set the animators position to where the ragdoll (root) lands, Often times my ragdoll will go flying, and disabling the ragdoll lerps it back to the starting position with the animation. I can understand why this would happen, but I'm curious if there is any simple built in way around this? :)

    Enabling ragdoll mid-flip + some other forces, then disabling it once the character is offscreen: http://i.imgur.com/fC9bisl.gif
     
    Last edited: Sep 1, 2015
  30. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    Hey! i just saw this video on your youtube channel:
    and you said 1 year ago "as stated in the video, it does not use Final IK at all, its a completely separate project. I'll pick that up when Im done with Final IK :)"

    so, just quick question: is this possible now with Final IK?
     
    ksam2 likes this.
  31. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Thanks, Carlos, I'll keep that in mind when I get to the next tutorials hopefully tomorrow.
    In the meanwhile, can't you just drop the objects by unparenting them and making their Rigidbodies non-kinematic?

    Hi, currently the RagdollUtility does not support that, I mean you won't be able to use IK on top of your partial ragdoll. But you can just enable the Rigidbodies of the limb you wish to ragdoll and keep the connected body kinematic, that should work fine as long as you don't have IK on it.
    In the current Unity5.2 beta there is a bug with the Animator that also breaks RagdollUtility. I have reported it so I hope they fix it before it is released.

    When you disable the ragdoll and want to get up, you should play some kind of getting up animation and just set the animator's position to where the ragdoll's hips Rigidbody is.

    Hi, no, not with Final IK. It's another tool, the PuppetMaster, that is technically ready and in private beta testing as we speak.
    It has taken much longer than I anticipated because Final IK has taken a lot more of my time and has grown a lot since that time, but it's coming :)

    Cheers,
    Pärtel
     
    DMeville and ksam2 like this.
  32. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    any chance to participate? ;)
     
  33. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    could you give an example how you would "ragdoll" one arm in the ragdoll utility scene? cause i think thats really interesting but somehow cant figure it out :/
     
  34. RFLG

    RFLG

    Joined:
    Feb 7, 2011
    Posts:
    153
    Thanks for the help Partel!

    Following up on this implementation, I've run into something I guess could be a n00b issue:

    -After finishing the effector part, I've decided to add some Interactions by using the Interaction system and related components. Now, if the interaction system component is turned on, I have no control over the effectors I created previously.

    What I did was:

    -Add Interaction System component to my FBBIK model.
    -Add interaction objects + targets when required
    -Write a simple script to trigger/control the interactions

    What happens:

    -If interaction system is On: all the interactions are working properly, but I lost all Effector control
    -If interaction system is Off: no interactions, Effector control works properly

    Can you help me sort this out? Can I combine these two approaches or are they mutualy exclusive?

    Thank you for the time taken with this matter!
     
  35. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Hi Partel, that make the trick. I get it working, although the video tutorial would be very useful to understand better all implications.

    Thanks for pointing me in the right direction :)
     
  36. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    @Partel Lang @Der_Kevin Yes, I'm not too sure about this either. It seems that the ragdolls only take effect when the animator is disabled, which of course doesn't allow for things to be partially animated and partially ragdolled, unless I'm missing something obvious. Is there a secret to enabling rigidbodies? (using the ragdoll wizard it creates rigidbody components on the joint transforms of the skeleton, of which the rigidbody component has no individual enable-box), setting specific ones to kinematic does not work for me either.. :)
     
    Last edited: Sep 2, 2015
  37. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    One more thing Partel, now that I'm getting more involved with the Interaction Trigger (amazing component btw) and get to pick / drop objects...

    As the player picks the ball...instead of walking with the ball(hand) down...How could I make the player raise the hand-ball until I decide to drop it? (I don't have any animation and want to make it with Final IK, so the player could walk, run and idle with the hand lifted)

    This would be the same as the example I was talking about above. If a player lift a box with two hands, using the interaction trigger, you would want the player to adopt a custom position like the one in the two handed sample, so you could move and then release the box in a position to return to the normal idle-walk-cycle.
     
  38. mischaTGE

    mischaTGE

    Joined:
    Aug 24, 2015
    Posts:
    7
    Yes the foldout is completly empty. We tested the package itself by importing it in an empty project, it worked. We are using mixed serialization, as we are using Pixelcrushers DialogSystem which depends on this setting. We also have some costume Importer script that Scales the rigs of our models.
     
  39. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Hey, if you are interested, drop me a few lines (contact@root-motion.com) about who you are and what you'd like to try the PuppetMaster on, you know like a little motivation letter. :)

    I totally forgot about the Animator overwriting physics. Never fear, it can still be done, try a script like this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PartialRagdoll : MonoBehaviour {
    5.  
    6.     [System.Serializable]
    7.     public class RigidBone {
    8.         public Rigidbody rigidbody;
    9.  
    10.         private Vector3 position;
    11.         private Quaternion rotation;
    12.  
    13.         public void Initiate() {
    14.             position = rigidbody.position;
    15.             rotation = rigidbody.rotation;
    16.         }
    17.  
    18.         // Move the rigidbody back to where it was last physically solved to
    19.         public void BeforePhysics() {
    20.             rigidbody.MovePosition(position);
    21.             rigidbody.MoveRotation(rotation);
    22.         }
    23.  
    24.         // Store the phsycally solved position and rotation
    25.         public void BeforeAnimation() {
    26.             position = rigidbody.position;
    27.             rotation = rigidbody.rotation;
    28.         }
    29.  
    30.         // Lerp from animated state to ragdoll state
    31.         public void AfterAnimation(float weight, bool mapPosition) {
    32.             rigidbody.isKinematic = weight <= 0f;
    33.  
    34.             if (weight <= 0f) return;
    35.  
    36.             if (mapPosition) {
    37.                 rigidbody.transform.localPosition = Vector3.Lerp(rigidbody.transform.localPosition, rigidbody.transform.parent.InverseTransformPoint(position), weight);
    38.             }
    39.             rigidbody.transform.localRotation = Quaternion.Slerp(rigidbody.transform.localRotation, Quaternion.Inverse(rigidbody.transform.parent.rotation) * rotation, weight);
    40.         }
    41.     }
    42.  
    43.     [Range(0f, 1f)] public float weight = 1f;
    44.     public bool mapPosition;
    45.     public RigidBone[] rigidbones;
    46.  
    47.     private bool fixedFrame;
    48.     private bool updateFrame;
    49.  
    50.     void Start() {
    51.         foreach (RigidBone r in rigidbones) r.Initiate();
    52.     }
    53.  
    54.     void FixedUpdate() {
    55.         fixedFrame = true;
    56.  
    57.         if (updateFrame) {
    58.             foreach (RigidBone r in rigidbones) r.BeforePhysics();
    59.             updateFrame = false;
    60.         }
    61.     }
    62.  
    63.  
    64.     void Update() {
    65.         updateFrame = true;
    66.  
    67.         if (fixedFrame) {
    68.             foreach (RigidBone r in rigidbones) r.BeforeAnimation();
    69.         }
    70.     }
    71.  
    72.     // Mecanim updates here
    73.  
    74.     void LateUpdate() {
    75.         foreach (RigidBone r in rigidbones) r.AfterAnimation(weight, mapPosition);
    76.  
    77.         fixedFrame = false;
    78.     }
    79. }
    80.  
    Just open the RagdollUtility scene, get rid of the FBBIK and RagdollUtility components, and add this one instead.
    Assign for example the left upper arm and forearm rigidbodies to it and play the scene. :) Make sure the Animator is in Normal update mode.

    Hi! Yes, the InteractionSystem needs to use the effectors too, so there will be a conflict.
    Unless you convert you effector controller to use effector.positionOffset instead of effector.position and positionWeight. The latter overrides the former if positionWeight > 0, so the InteractionSystem would be working smoothly on top of your other procedural animations.
    So basically just replace
    Code (CSharp):
    1. ik.solver.leftHandEffector.position = something;
    with
    Code (CSharp):
    1. ik.solver.leftHandEffector.positionOffset += something - ik.solver.leftHandEffector.bone.position;
    If you're wondering why I'm using += instead of =, it's because FBBIK resets positionOffset to zero after each update. That enables us to use positionOffset additively by multiple offset modifiers.

    Hi!
    I just finished the 2nd part of the Interaction System tutorial series that answers exactly this question. :)


    In that case it must be a Unity bug, as I said, I am not using any custom editors (or any other fancy stuff for that matter) with the Grounder, it should work out of the box. I will look into it though, maybe I can find a solution.

    Cheers,
    Pärtel
     
    Last edited: Sep 2, 2015
    DMeville likes this.
  40. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    hm.. i think i did something wrong o.o

    left - your ragdoll guide - kinematic on upperarm and lowerarm turned off - but with kinematic on it behaves the same way
    middle - original
    right - sleeping ragdoll
     
  41. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,548
    Sry, fixed the script in the previous post, try again please.
     
    DMeville likes this.
  42. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    works perfect now, thank you :)
     
    DMeville and Partel-Lang like this.
  43. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Hi Partel!

    Amazing as always, this video is priceless, just see it and will try it with my own test scene.
    keeping to watch the next video about animations and what could be done with this.

    Thanks!
     
    Partel-Lang likes this.
  44. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Hi Partel.

    I have everything working except for 2 issues.

    1.When aiming with 2 handed weapons the off hand doesn't stay relative to the right. I've followed the video tutorial but can't get it to move.

    2. I'm using parts of your FPSAiming script and when looking down the sights the target gun and the player's gun rotate in a strange way. They shouldn't be rotating at all.

    Code (CSharp):
    1.         [Range(0f, 1f)]
    2.         public float aimWeight = 1f; // The weight if aiming aimTransform towrd camera forward
    3.         [Range(0f, 1f)]
    4.         public float sightWeight = 0f; // The weight of looking dowmn the sight (multiplied by aimWeight)
    5.         [Range(0f, 180f)]
    6.         public float maxAngle = 40f; // The maximum Aiming offset from character forwawrd
    7.  
    8.         //FinalIK Stuff
    9.         [SerializeField]
    10.         FullBodyBipedIK ik;
    11.  
    12.         private IKEffector leftHand { get { return ik.solver.leftHandEffector; } }
    13.         private IKEffector rightHand { get { return ik.solver.rightHandEffector; } }
    14.         [SerializeField]
    15.         AimIK aimIK;
    16.         [SerializeField]
    17.         GrounderFBBIK grounder;
    18.         [SerializeField]
    19.         InteractionSystem interactionSystem;
    20.         [SerializeField]
    21.         LookAtIK lookAtIK;
    22.  
    23.         [SerializeField]
    24.         Animator animator;
    25.         public CameraControllerFPS cam;
    26.  
    27.         //Default Positions
    28.         private Vector3 gunTargetDefaultLocalPosition;
    29.         private Quaternion gunTargetDefaultLocalRotation;
    30.         private Vector3 camDefaultLocalPosition;
    31.         private Vector3 camRelativeToGunTarget;
    32.         private Quaternion leftHandRotationRelative;
    33.  
    34.         // Use this for initialization
    35.         void Start()
    36.         {
    37.             // Remember some default local positions
    38.            
    39.             camDefaultLocalPosition = cam.transform.localPosition;
    40.  
    41.             aimIK = GetComponent<AimIK>();
    42.             lookAtIK = GetComponent<LookAtIK>();
    43.             //Disable the cam so we can update it manually
    44.             cam.enabled = false;
    45.             aimIK.Disable();
    46.             //ik.Disable();
    47.             lookAtIK.Disable();
    48.             interactionSystem.OnInteractionPickUp += OnInteractionPickUp;
    49.             ik.solver.OnPostUpdate += PostFBBIK;
    50.         }
    51.  
    52.         void Update()
    53.         {
    54.  
    55.             if(Input.GetKeyDown(KeyCode.L))
    56.                 lookAtIK.solver.target = lookhere.transform;
    57.         }
    58.         void FixedUpdate()
    59.         {
    60.             //Make sure this works with Animate Physics
    61.             updateFrame = true;
    62.         }
    63.        
    64.         // Update is called once per frame
    65.         void LateUpdate()
    66.         {
    67.             //Make sure this works with Animate Physics
    68.             if (!animatePhysics) updateFrame = true;
    69.             if (!updateFrame) return;
    70.             updateFrame = false;
    71.  
    72.            
    73.             // Put the camera back to its default local position relative to the head
    74.             cam.transform.localPosition = camDefaultLocalPosition;
    75.  
    76.             if (gunTarget!=null)
    77.             //Remember the Camera's position relative to the aimTransform target
    78.             camRelativeToGunTarget = gunTarget.InverseTransformPoint(cam.transform.position);
    79.  
    80.             //Update the Camera
    81.             cam.LateUpdate();
    82.  
    83.             //Rotating the root of the character if it is past maxAngle   from the camera forawrd
    84.             RotateCharacter();
    85.             Pickup();
    86.             if (interactionSystem.inInteraction)
    87.                 return;
    88.  
    89.             //Set FBBIK weight for the hands
    90.             leftHand.positionWeight = aimWeight > 0 && sightWeight > 0 ? 1f : 0f;
    91.             rightHand.positionWeight = leftHand.positionWeight;
    92.  
    93.       if (holdingWeapon == true)
    94.             {
    95.                 if (useAim)
    96.                     Aiming();
    97.             }
    98.             else
    99.                 HeadLookAt(lookAtTarget);
    100.  
    101.             LookDownTheSight();
    102.         }
    103.  
    104.         void PostFBBIK()
    105.         {
    106.             leftHand.bone.rotation = rightHand.bone.rotation * leftHandRotationRelative;
    107.         }
    108.  
    109.         void Actions()
    110.         {
    111.             if (Input.GetKeyDown(KeyCode.F)) useAim = !useAim;
    112.  
    113.             aimWeight = useAim ? 1f : 0f;
    114.  
    115.             // Continuous lerping, no matter if the F key is down or not
    116.             aimIK.solver.IKPositionWeight = Mathf.MoveTowards(aimIK.solver.IKPositionWeight, aimWeight, Time.deltaTime * 3);
    117.  
    118.             // Make the first layer's weight the same as AimIK weight. This is the easiest way. You might want to use another variable that lerps to aimWeightTarget faster that AimIK weight.
    119.             animator.SetLayerWeight(1, aimIK.solver.IKPositionWeight);
    120.         }
    121.         private void Aiming()
    122.         {
    123.             if (aimWeight <= 0f) return;
    124.             Debug.Log("Aiming");
    125.             // Remember the rotation of the camera because we need to reset it later so the IK would not interfere with the rotating of the camera
    126.             Quaternion camRotation = cam.transform.rotation;
    127.  
    128.             // Aim the gun towards camera forward
    129.             aimIK.solver.IKPosition = cam.transform.position + cam.transform.forward * 10f;
    130.             //aimIK.solver.IKPositionWeight = aimWeight;
    131.             aimIK.solver.Update();
    132.             cam.transform.rotation = camRotation;
    133.         }
    134.  
    135.         private void LookDownTheSight()
    136.         {
    137.             float sW = aimWeight * sightWeight;
    138.             if (sW <= 0f) return;
    139.  
    140.             // Interpolate the gunTarget from the current animated position of the gun to the position fixed to the camera
    141.             gunTarget.position = Vector3.Lerp(gun.position, gunTarget.parent.TransformPoint(gunTargetDefaultLocalPosition), sW);
    142.             gunTarget.rotation = Quaternion.Lerp(gun.rotation, gunTarget.parent.rotation * gunTargetDefaultLocalRotation, sW);
    143.  
    144.             // Get the current positions of the hands relative to the gun
    145.             Vector3 leftHandRelativePosition = gun.InverseTransformPoint(leftHand.bone.position);
    146.             Vector3 rightHandRelativePosition = gun.InverseTransformPoint(rightHand.bone.position);
    147.  
    148.             // Get the current rotations of the hands relative to the gun
    149.             Quaternion leftHandRelativeRotation = Quaternion.Inverse(gun.rotation) * leftHand.bone.rotation;
    150.             Quaternion rightHandRelativeRotation = Quaternion.Inverse(gun.rotation) * rightHand.bone.rotation;
    151.  
    152.             // Position the hands to the gun target the same way they are positioned on the gun
    153.             leftHand.position = gunTarget.TransformPoint(leftHandRelativePosition);
    154.             rightHand.position = gunTarget.TransformPoint(rightHandRelativePosition);
    155.  
    156.             // Make sure the head does not rotate
    157.             ik.solver.headMapping.maintainRotationWeight = 1f;
    158.  
    159.             // Update FBBIK
    160.             ik.solver.Update();
    161.  
    162.             // Rotate the hand bones relative to the gun target the same way they are rotated relative to the gun
    163.             leftHand.bone.rotation = gunTarget.rotation * leftHandRelativeRotation;
    164.             rightHand.bone.rotation = gunTarget.rotation * rightHandRelativeRotation;
    165.  
    166.             // Position the camera to where it was before FBBIK relative to the gun
    167.             cam.transform.position = Vector3.Lerp(cam.transform.position, gun.transform.TransformPoint(camRelativeToGunTarget), sW);
    168.         }
    169.  
    170.         // Rotating the root of the character if it is past maxAngle from the camera forward
    171.         private void RotateCharacter()
    172.         {
    173.             if (maxAngle >= 180f) return;
    174.  
    175.             // If no angular difference is allowed, just rotate the character to the flattened camera forward
    176.             if (maxAngle <= 0f)
    177.             {
    178.                 transform.rotation = Quaternion.LookRotation(new Vector3(cam.transform.forward.x, 0f, cam.transform.forward.z));
    179.                 return;
    180.             }
    181.  
    182.             // Get camera forward in the character's rotation space
    183.             Vector3 camRelative = transform.InverseTransformDirection(cam.transform.forward);
    184.  
    185.             // Get the angle of the camera forward relative to the character forward
    186.             float angle = Mathf.Atan2(camRelative.x, camRelative.z) * Mathf.Rad2Deg;
    187.  
    188.             // Making sure the angle does not exceed maxangle
    189.             if (Mathf.Abs(angle) > Mathf.Abs(maxAngle))
    190.             {
    191.                 float a = angle - maxAngle;
    192.                 if (angle < 0f) a = angle + maxAngle;
    193.                 transform.rotation = Quaternion.AngleAxis(a, transform.up) * transform.rotation;
    194.             }
    195.         }
    196.  
    197.  
     
  45. RFLG

    RFLG

    Joined:
    Feb 7, 2011
    Posts:
    153
    Hello!

    Well your solution worked, but not perfectly:

    -Now the character does respond to both effector movement but also to interactions. Which is great!

    However it is suffering a massive offset. The first time I applied your fix, my model was completely streched forwards by it's wrists. I had to apply a couple of modifiers to reduce the offset ammount and return it to the "normal" pose, and even now it still streches a bit upwards. This result is however far from perfect, since the movement becomed stiff and in some cases limited (arms just don't go to certain positions anymore), when it used to be very fluid.

    Any ideas on what could be happening? How can I mitigate this excessive offset and get a more "normal" movement?

    Thanks for all the help Partel!
     
  46. carlosrovira

    carlosrovira

    Joined:
    Dec 23, 2014
    Posts:
    58
    Hi Partel,

    The Offset pose seems like a framework component, not a Script for demo purposes. Could I suggest to move this kind of Scripts to RootMotion.FinalIK namespace? I think, in the end people using Final IK could remove examples from their projects and keep the main library.

    What do you think?
     
  47. Partel-Lang

    Partel-Lang

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

    I can't really debug this code like that, there are too many things missing, I wouldn't know where to start.
    But I did notice that in OnPostFBBIK() you have this line:
    Code (CSharp):
    1. leftHand.bone.rotation = rightHand.bone.rotation * leftHandRotationRelative;
    but leftHandRotationRelative is never assigned to anything.
    you need to add
    Code (CSharp):
    1. leftHandRotationRelative = Quaternion.Inverse(rightHand.bone.rotation) * leftHand.bone.rotation;
    to somewhere in LateUpdate where no IK is applied yet.

    About the second question, try commenting out chunks of code until you find out which part is making it rotate.

    Hi!
    Sorry I can't really understand what's going on, can you send me some code and screenshots or something? It should really look the same.

    Hi again, yea I was actually thinking the same when I made that video, I'll change the namespace :)

    Cheers,
    Pärtel
     
  48. RFLG

    RFLG

    Joined:
    Feb 7, 2011
    Posts:
    153
    Hey Partel, thanks for the feedback! Here are some screenshots of what is happening on all cases. I can share a bit more details with you, but I'll have to PM or email you. Let me know if that would be preferable ;)

    So, some pictures!

    This is the intended idle state. On the screenshot I have an FBBIK and effectors mapped. Interaction system OFF. Effectors work perfectly, movement is smooth as intended:



    Then I applied your correction and turned ON the Interaction system, this is what happens:



    I figured that the hand effector offset is a way bit too much off, since the character is literally pulled forwards. Movement is still smooth, but the damage to the pose is massive.

    Then I applied a modifier to the offset calculation you provided, to try and reduce the influence of the latter on the pose. This was my best result:


    Notice the upwards "streching" on the torso and legs, the pose was supposed to be identical to the one on the first picture, but he looks like he is being lifted or pulled up. The arms are not and issue, since I had the controller turned on, so they were moving. If I leave the controller alone, they stay on pose as intended.

    Basically if I could fix the offset I have on picture 2, then everything would be just perfect. The modifiers I use on picture 3 do correct the pose (or almost), but they also make the character's movement more "stiff" and rather limited, while on pictures one and two the movement is really fluid.

    Let me know what you think! And thanks for all the help!!

    Edit: I sent you a PM with further details regarding the implementation. Hope it helps explaining my issue ;)
     
    Last edited: Sep 4, 2015
  49. RFLG

    RFLG

    Joined:
    Feb 7, 2011
    Posts:
    153
    Also, with Pickup mode enabled, my objects get a very weird rotation after being parented to the effector. It could be the bones...Anyway to correct/mitigate this issue?
     
    Last edited: Sep 7, 2015
  50. HiThatGirl

    HiThatGirl

    Joined:
    Nov 12, 2014
    Posts:
    19
    I hava a question,I want to make character from Standing State to Sit down State than to Pick up a glass of wine
    but ,I can only do it from Standing to Sit down , I use InteractionSystem.
    I hope to give me a Demo look.
    Thank you!
    I'm in a hurry.

    20150907184513.jpg
     
    Last edited: Sep 7, 2015