Search Unity

Automating limbs rotations

Discussion in 'Scripting' started by Eideren, Mar 27, 2014.

  1. Eideren

    Eideren

    Joined:
    Aug 20, 2013
    Posts:
    309
    I'm building an Inverse Kinematics rig and am currently automating the movement of the clavicle and the scapula.
    What I want to do is use the Y rotation of the shoulder to rotate the y axis of the clavicle to a maximum of +40~50 and -20 (it shouldn't change the scapula's local rotation if a parent rotates) but now I have stuttering problems once it crosses the 180 cap because the code reverse the rotation at that moment, the result rotation isnt precise too, probably because of the mess when calculating those angles.

    I still did not find how to turn the Z axis correctly when the body rotates, and still have to code a position and rotation transform for the scapula by using half or less of the clavicle rotation, wich by using this method will be even more buggy.

    Would it be possible to use quaternions for this? If so, how ?
    Code (csharp):
    1. void CalculateR_Scapula(){
    2.        //Y axis rotation
    3.        float RotY =  R_Shoulder.eulerAngles.y;
    4.        //Avatar = the highest parent in the hierarchy wich moves and rotate the whole body when the player walk
    5.        float BodyRotationY = Avatar.transform.eulerAngles.y;
    6.  
    7.        if(BodyRotationY > 180){
    8.          BodyRotationY = BodyRotationY - 360;
    9.        }
    10.  
    11.        if(RotY > 180){
    12.          RotY = Mathf.Clamp(RotY, 310 + BodyRotationY, 360 + BodyRotationY);
    13.        }
    14.        else {RotY = Mathf.Clamp(RotY, 0 + BodyRotationY, 20 + BodyRotationY);}
    15.  
    16.  
    17.        //Z axis Rotation
    18.        float RotZ = R_Shoulder.eulerAngles.z;
    19.        //t-pose y axis = 180, so clamp from -5 to + 40
    20.        RotZ = Mathf.Clamp (RotZ, BaseRotR_Clavicle.z-5, BaseRotR_Clavicle.z+40);
    21.  
    22.        //BaseRot = the rotation of each transform at void Start()
    23.        Quaternion NewRot = Quaternion.Euler (BaseRotR_Clavicle.x, BaseRotR_Clavicle.y + RotY, BaseRotR_Clavicle.z + RotZ + 180);
    24.        //Used to smooth out the stuttering when Y rotation = 180, doesn't really work that well at all
    25.        R_Clavicle.transform.rotation = Quaternion.Lerp (R_Clavicle.transform.rotation, NewRot, Time.deltaTime * 20);
    26.     }
    $Untitled-1.png

    Thank you for taking the time to read.
     
  2. Eideren

    Eideren

    Joined:
    Aug 20, 2013
    Posts:
    309
    I tried another way by creating a new gameobject and using it to compare the rotation of the shoulder with the avatar's, but this time for some reason the local rotation keeps changing ...

    Code (csharp):
    1. void CalculateR_Scapula(){
    2.         Quaternion AvatarRot =  Quaternion.Euler(0, Avatar.transform.eulerAngles.y, 0);
    3.         Quaternion L_ShoulderRot =  Quaternion.Euler(0, L_Shoulder.transform.eulerAngles.y, 0);
    4.  
    5.         float DiffY =  Quaternion.Angle(AvatarRot, L_ShoulderRot);
    6.  
    7.         ClavicleAngle.transform.parent = L_Clavicle;
    8.         ClavicleAngle.transform.localPosition = Vector3.zero;
    9.         ClavicleAngle.transform.localEulerAngles = Vector3.zero;
    10.         ClavicleAngle.transform.parent = Avatar.transform;
    11.         //if(ClavicleAngle.transform.localEulerAngles.y > 180)DiffY = -(Mathf.Abs(DiffY));
    12.         //L_Clavicle.transform.eulerAngles = new Vector3 (L_Clavicle.transform.eulerAngles.x, BaseRotL_Clavicle.y + DiffY/2, L_Clavicle.transform.eulerAngles.z);
    13.  
    14.  
    15.         print (ClavicleAngle.transform.localEulerAngles);
    16.     }
     
  3. Eideren

    Eideren

    Joined:
    Aug 20, 2013
    Posts:
    309
    Well, i completely abandonned the modification of eulerangles directly and the result looks fine till the spine and the hips arent zeroed, the position of the scapula isn't correct nor is the clavicle's rotation.

    Code (csharp):
    1.     void CalculateR_Scapula(){
    2.         R_Lock.transform.position = R_Elbow.transform.position;
    3.         R_Lock.transform.parent = Spine_End;
    4.         R_Lock.transform.localPosition = new Vector3(Mathf.Clamp(R_Lock.transform.localPosition.x, 0.3f, 100),
    5.                                                      Mathf.Clamp (R_Lock.transform.localPosition.y, 0, 0.2f),
    6.                                                      Mathf.Clamp (R_Lock.transform.localPosition.z, -0.1f, 0.3f));
    7.         R_ClavicleAxisCorrection.transform.position = R_Clavicle.position;
    8.         R_Clavicle.parent = R_ClavicleAxisCorrection.transform;
    9.         R_Clavicle.transform.localEulerAngles = R_RotInHelper;
    10.         R_ClavicleAxisCorrection.transform.LookAt(R_Lock.transform.position, R_ClavicleAxisCorrection.transform.up);//-R_Clavicle.forward
    11.         //R_ClavicleAxisCorrection.transform.localEulerAngles = new Vector3(R_ClavicleAxisCorrection.transform.localEulerAngles.x, R_ClavicleAxisCorrection.transform.localEulerAngles.y, R_LockZ);
    12.        
    13.  
    14.         if(R_Lock.transform.localPosition.z > 0){
    15.             R_Scapula.transform.localPosition = new Vector3(BasePosR_Scapula.x + R_Lock.transform.localPosition.z / 10, BasePosR_Scapula.y, BasePosR_Scapula.z + R_Lock.transform.localPosition.z / 10);
    16.         }
    17.         else{
    18.             R_Scapula.transform.localPosition = new Vector3(BasePosR_Scapula.x + R_Lock.transform.localPosition.z / 3, BasePosR_Scapula.y, BasePosR_Scapula.z + R_Lock.transform.localPosition.z / 10);
    19.         }
    20.         R_Scapula.transform.localEulerAngles = new Vector3(BaseRotR_Scapula.x, -R_Lock.transform.localPosition.z*100, BaseRotR_Scapula.z);
    21.         R_Clavicle.parent = Spine_End.transform;
    22.     }
    Here is a .unityproject wich should recreate my problem, rotate the spine and hips controllers on play mode in the edit window, you will likely need to activate the textured+wireframe view to make it more obvious.
     

    Attached Files:

    Last edited: Apr 9, 2014