- Home /
Animate arm to grab object with IK/Mecanim
Hi folks,
I'm new to Unity 4 and its Mecanim Animation System. I've watched the Mecanim Tutorial from Unity and was impressed what is possible with this. But what they have forgotten is how to grab objects with Inverse Kinematics. I know some scripts to hold an object with IK, for example the IKControl script, which tells how the callbacks like OnAnimatorIK are working.
When I run the script my avatars arm moves into the target objects direction and when I move the target object, the arm is following it. Then I parented and repositioned the target object to the avatars hand. But now I want an animation to grab the object.
How can I do something like that? That the arm moves to the object, then IKCtrl grabs it and the arm moves back with the object attached to the arms hand? I have no idea..
This is my IKCtrl script, which only attaches/deattaches the object:
using UnityEngine;
using System;
using System.Collections;
[RequireComponent(typeof(Animator))]
public class IKCtrl : MonoBehaviour {
protected Animator animator;
public bool ikActive = false;
public GameObject bikeRepair;
public Transform rightHandObj = null;
private float weight = 0.0f;
private Rigidbody tempRigid;
void Start ()
{
animator = GetComponent<Animator>();
}
void Update () {
Transform cam = Camera.main.transform;
Ray ray = new Ray(cam.position, cam.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1)) {
GameObject gO = hit.collider.gameObject;
Grabable comp = null;
if (comp = (Grabable) gO.GetComponent("Grabable")) {
if(!ikActive)
comp.hover = true;
if (Input.GetKeyDown(KeyCode.E)) {
if(!ikActive) {
ikActive = true;
rightHandObj = gO.transform;
rightHandObj.transform.parent = GameObject.Find("Right_Middle_Finger_Joint_01a").transform;
rightHandObj.position = GameObject.Find("Right_Middle_Finger_Joint_01a").transform.position;
tempRigid = rightHandObj.rigidbody;
Destroy(rightHandObj.rigidbody);
return;
}
}
}
}
// drop it
if (Input.GetKeyDown(KeyCode.E)) {
if (ikActive && rightHandObj != null) {
ikActive = false;
rightHandObj.parent = bikeRepair.transform;
rightHandObj.gameObject.AddComponent<Rigidbody>();
tempRigid = null;
rightHandObj = null;
}
}
}
//a callback for calculating IK
void OnAnimatorIK() {
if(animator) {
//if the IK is active, set the position and rotation directly to the goal.
if(ikActive) {
weight = 1.0f;
//for the right hand means position and rotation will be at the IK goal (the place the character wants to grab)
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, weight);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, weight);
if(rightHandObj != null) {
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
}
}
//if the IK is not active, set the position and rotation of the hand back to the original position
else {
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, weight);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, weight);
}
}
}
}