This is a work in progress-- There has been a lot of talk about IK, and not a lot of code... It works for an arm or something- I was working on turning it into a full fledged walking script when I had to return to other things. If you modify it, please repost the code for everyone to benefit. Soon, I'll clean this up and edit my post to make this clearer. Sorry to repost this, but it got lost in another thread, and I figure there are people who might be interested in developing it further, or have suggestions for optimization. If you have suggestions, I'll try to implement them as I have time. Code (csharp): var target : GameObject; private var targetT : Transform; var shoulder : Transform; var elbow : Transform; var hand : Transform; var targetOrient : Transform; var hips : Transform; var characterMain : Transform; private var shoulderLength : float = 0; private var elbowLength : float = 0; private var shoulderLengthSQ : float = 0; private var elbowLengthSQ : float = 0; private var distVec = Vector3.zero; private var distMag : float = 0.0; private var initialShoulder : Quaternion; private var initialElbow : Quaternion; private var shoulderAngle : float = 0.0; private var initialHips : float = 0.0; private var walkSpeed : float = .002; function Start (){ targetT = target.transform; targetT.position = hand.position; shoulderLengthSQ = (shoulder.position - elbow.position).sqrMagnitude; shoulderLength = Mathf.Sqrt(shoulderLengthSQ); elbowLengthSQ = (elbow.position - hand.position).sqrMagnitude; elbowLength = Mathf.Sqrt(elbowLengthSQ); initialShoulder = shoulder.localRotation; initialElbow = elbow.localRotation; initialHips = hips.position.y; } function Update () { //this calculation doesn't need to be every frame distVec = shoulder.position - targetT.position; distMag = distVec.sqrMagnitude; var realDist = Mathf.Sqrt(distMag); //shoulder angle shoulderAngle = 90 - Vector3.Angle(distVec, Vector3(1,0,0)); if (realDist > (elbowLength + shoulderLength)){ //no solution, reach for it elbow.localRotation = initialElbow; shoulder.localRotation = initialShoulder* Quaternion.AngleAxis(shoulderAngle, Vector3(0,0,1)); //shoulder.LookAt(target); } else if(realDist < (Mathf.Abs(elbowLength - shoulderLength))){ //no solution, too close } else{ //shoulder.LookAt(target); //idealElbow rotation elbow.localRotation = Quaternion.AngleAxis(180-Mathf.Acos((shoulderLengthSQ + elbowLengthSQ - distMag)/(shoulderLength*elbowLength*2)) * Mathf.Rad2Deg, Vector3(0,0,1))* initialElbow; //TODO Change shoulder rotation based on elbow lock shoulder.localRotation = Quaternion.AngleAxis(shoulderAngle-Mathf.Acos((shoulderLengthSQ - elbowLengthSQ + distMag)/(shoulderLength*realDist*2)) * Mathf.Rad2Deg,Vector3(1,0,0))* initialShoulder; }
perfect, that's exactly what I'm looking for. Should get me up to speed with unity scripting too. many thanks.