Search Unity

IK Code WIP

Discussion in 'Scripting' started by Brian-Kehrer, May 2, 2008.

  1. Brian-Kehrer

    Brian-Kehrer

    Joined:
    Nov 7, 2006
    Posts:
    411
    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):
    1.  
    2. var target : GameObject;
    3. private var targetT : Transform;
    4. var shoulder : Transform;
    5. var elbow : Transform;
    6. var hand : Transform;
    7. var targetOrient : Transform;
    8.  
    9.  
    10. var hips : Transform;
    11. var characterMain : Transform;
    12. private var shoulderLength : float = 0;
    13. private var elbowLength : float = 0;
    14.  
    15. private var shoulderLengthSQ : float = 0;
    16. private var elbowLengthSQ : float = 0;
    17.  
    18. private var distVec = Vector3.zero;
    19. private var distMag : float = 0.0;
    20.  
    21. private var initialShoulder : Quaternion;
    22. private var initialElbow : Quaternion;
    23.  
    24. private var shoulderAngle : float = 0.0;
    25.  
    26. private var initialHips : float = 0.0;
    27.  
    28.  
    29. private var walkSpeed : float = .002;
    30.  
    31. function Start (){
    32.     targetT = target.transform;
    33.     targetT.position = hand.position;
    34.    
    35.     shoulderLengthSQ = (shoulder.position - elbow.position).sqrMagnitude;
    36.     shoulderLength = Mathf.Sqrt(shoulderLengthSQ);
    37.  
    38.     elbowLengthSQ = (elbow.position - hand.position).sqrMagnitude;
    39.     elbowLength = Mathf.Sqrt(elbowLengthSQ);
    40.    
    41.     initialShoulder = shoulder.localRotation;
    42.     initialElbow = elbow.localRotation;
    43.    
    44.     initialHips = hips.position.y;
    45. }
    46.  
    47.  
    48. function Update () {
    49.    //this calculation doesn't need to be every frame
    50.    distVec = shoulder.position - targetT.position;
    51.    distMag = distVec.sqrMagnitude;
    52.    var realDist = Mathf.Sqrt(distMag);
    53.    //shoulder angle
    54.     shoulderAngle = 90 - Vector3.Angle(distVec, Vector3(1,0,0));
    55.  
    56.    
    57.    if (realDist > (elbowLength + shoulderLength)){
    58.       //no solution, reach for it
    59.       elbow.localRotation = initialElbow;
    60.       shoulder.localRotation = initialShoulder* Quaternion.AngleAxis(shoulderAngle, Vector3(0,0,1));
    61.       //shoulder.LookAt(target);
    62.    }
    63.    else if(realDist < (Mathf.Abs(elbowLength - shoulderLength))){
    64.       //no solution, too close
    65.    }
    66.    else{
    67.        
    68.       //shoulder.LookAt(target);
    69.       //idealElbow rotation
    70.       elbow.localRotation = Quaternion.AngleAxis(180-Mathf.Acos((shoulderLengthSQ + elbowLengthSQ - distMag)/(shoulderLength*elbowLength*2)) * Mathf.Rad2Deg, Vector3(0,0,1))* initialElbow;
    71.      
    72.       //TODO Change shoulder rotation based on elbow lock
    73.       shoulder.localRotation = Quaternion.AngleAxis(shoulderAngle-Mathf.Acos((shoulderLengthSQ - elbowLengthSQ + distMag)/(shoulderLength*realDist*2)) * Mathf.Rad2Deg,Vector3(1,0,0))* initialShoulder;
    74.    }
    75.  
     
  2. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,598
    perfect, that's exactly what I'm looking for. :D
    Should get me up to speed with unity scripting too. many thanks.