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

IK to animated position a frame behind

Discussion in 'Animation' started by skateborden, Aug 13, 2015.

  1. skateborden

    skateborden

    Joined:
    Apr 1, 2009
    Posts:
    35
    I have a guitar player character, and I'm using IK to move it's hand to the frets on the guitar. I have empty GameObjects that are children of the guitar model that I use to know the position of the frets on the guitar. In OnAnimateIK I set the IK position of the character's hand to the transform position of the fret corresponding to the note the guitar player is playing. The guitar player has dance animations on another layer that change the position of the guitar, and thus the positions of the frets that are it's children.

    The problem is that the transform positions that OnAnimateIK sees are the positions before the animation effects the guitar position, essentially the position from the last frame, so the hand position is always a frame behind.

    If anyone knows a better approach to this or a workaround I'd appreciate it. Otherwise some way to get the position of objects after animations have been applied in OnAnimateIK would be a really useful addition to Unity's animation API.
     
  2. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    if you look closely for the OnAnimatorIK callback there is a int parameter fro the layer index.
    http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorIK.html

    This is exactly for this user case. Simply create another layer after your dance animation layer and check IK pass on this layer.

    Then in your OnAnimatorIK callback do your IK only when the layer index is equal to your new IK layer index
     
  3. skateborden

    skateborden

    Joined:
    Apr 1, 2009
    Posts:
    35
    @Mecanim.Dev thank you for the quick response. That seems like a logical way for it work, however it isn't working. I wasn't previously checking the layer index parameter in OnAnimateIK because I only have one IK layer (layer 3), which is after the dance layer (layer 1). I just added checking for the layer index and I am still getting the unchanged fret transform position in OnAnimateIK on layer 3, but it is changed when I log it in LateUpdate. As a test I also turned on IK on layer 1, logging the positions in OnAnimateIK and the position was the same on layer 1 and layer 3.
     
  4. Mecanim-Dev

    Mecanim-Dev

    Unity Technologies

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It should work, this how our example Bear apocalypse do work, we have two ik pass, the first one is a look at that change the whole upper body and then on the next pass we fix the hand on the gun with IK.

    Does your guitar props is parented to your character transform hierarchy or you are updating the guitar position manually in a script?
     
    theANMATOR2b likes this.
  5. skateborden

    skateborden

    Joined:
    Apr 1, 2009
    Posts:
    35
    I figured out the issue. The guitar and it's fret locators were a part of the model, and I had "Optimize Game Objects" turned on in the model Rig import settings, with the fret locator transforms exposed. If I turn off "Optimize Game Objects" it works.

    Thank you for you help and for pointing me at the Bear apocalypse demo, looking at it was helpful to narrow down what I was doing differently. I have submitted a bug report (case 719821) with an example project, as I think this kind of IK usage should still work when using "Optimize Game Objects."
     
    theANMATOR2b likes this.