Search code examples
animationunity-game-engineinverse-kinematics

Trying to use Inverse Kinematics in Unity3D to make character put hands on his gun


as you can see, the hands are just being put weirdly infront of the character. the righthandhold and lefthandhold are the gameobjects whose positions the hands are supposed to go on.

left screenshot is in play mode, the middle screenshot is not, so no IK there. screenshots the source code (adapted from a unity example):

void OnAnimatorIK(int layerIndex) {
    float aim = 1f;

    if (layerIndex == 0) {
        if (player != null) {
            Vector3 target = player.transform.GetChild(0).position + Vector3.up;

            animator.SetLookAtPosition(target);
            animator.SetLookAtWeight(aim, 0.5f, 0.5f, 0.0f, 0.5f);

        }
    }

    if (layerIndex == 1) {
        if (leftHandOnGunPosition != null) {
            animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandOnGunPosition.transform.position);
            animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandOnGunPosition.transform.rotation);
            animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, aim);
            animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, aim);
        }

        if (rightHandOnGunPosition != null) {
            animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandOnGunPosition.transform.position);
            animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandOnGunPosition.transform.rotation);
            animator.SetIKPositionWeight(AvatarIKGoal.RightHand, aim);
            animator.SetIKRotationWeight(AvatarIKGoal.RightHand, aim);
        }
    }
}

can anyone tell me what i'm doing wrong?

update: i just noticed that the right hand is further forward than the left hand. just like the positions on the gun. for testing i swapped out the target positions for the hands and then the left was infront of the right hand. so it definitely tries to move the hands to the correct positions... just not quite getting there.

update2: i also tried turning off the lookat stuff (everything in if (layerIndex == 0)), just to make sure that wasnt screwing anything up. made no difference, other than that the wasn't look at the player anymore.


Solution

  • alright, seems the issue was that when i added the model, it was too high compared to the navmeshagent it was in. so i made a child-gameobject between the navmeshagent and the model and gave it a y of -1.

    i was able to temporarily fix the IK by adding + Vector3.up to the IK positions.

    proper solution was to remove that in-between-child with the y -1 and then change the base offset in the navmeshagent from 1 to 0.