Search Unity

"Simple" rotation constraints for IK

Discussion in 'Animation' started by Nyanpas, Aug 8, 2020.

  1. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    The greetings,
    I did not know exactly where to put this so I decided to put it here.

    I am working on IK for my rigs and found a way to get rotation constraints with as little code as possible. There might be even eleganter solutions, but compared to my previous "attempts" this is almost divine.

    What it does extra is keep the local up-axis local, and you can see a very clumsy demonstration of it here on her shin:

    riggeningser.gif
    The code is as follows:
    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Mathematics;
    3.  
    4. public class ConstrainTest: MonoBehaviour
    5. {
    6.     public Transform Form;
    7.    
    8.     public Vector3 EulerAnglers = Vector3.zero;
    9.  
    10.     public float2 Xlimits = new float2(-90f, 90f);
    11.     public float2 Ylimits = new float2(-90f, 90f);
    12.     public float2 Zlimits = new float2(-90f, 90f);
    13.  
    14.     private Quaternion _startRotation = Quaternion.identity;
    15.  
    16.     void Start()
    17.     {
    18.         if(!Form)
    19.         {
    20.             Form = transform;
    21.         }
    22.  
    23.         _startRotation = Form.localRotation;
    24.     }
    25.  
    26.     void Update()
    27.     {
    28.         EulerAnglers.x = math.clamp(EulerAnglers.x, Xlimits.x, Xlimits.y);
    29.         EulerAnglers.y = math.clamp(EulerAnglers.y, Ylimits.x, Ylimits.y);
    30.         EulerAnglers.z = math.clamp(EulerAnglers.z, Zlimits.x, Zlimits.y);
    31.  
    32.         Form.localRotation = _startRotation * Quaternion.Euler(new Vector3(EulerAnglers.x, 0f, EulerAnglers.z)) * Quaternion.Euler(new Vector3(0f, EulerAnglers.y, 0f));
    33.     }
    34. }
    It can be tested out by being put on a limb of choice and then spin around the publicly exposed variables in the inspector window.
     
  2. Rispat-Momit

    Rispat-Momit

    Joined:
    Feb 14, 2013
    Posts:
    266
    Hi there :)

    I tried to use the script in Unity 2017 and I am getting many different errors :/

    upload_2021-11-22_23-44-35.png
     
  3. razzraziel

    razzraziel

    Joined:
    Sep 13, 2018
    Posts:
    396
    Use Vector2 instead of float2s. It is using Unity.Mathematics.

    But still that approach has its limitations. Even if you limit them with 90 degrees they can go out of limits with combinations of x, y and z rotation. Arm rotations for example. There are some other ways like limiting rotation with a cone shape area that limits the child bone movement.
     
    Rispat-Momit likes this.
  4. Rispat-Momit

    Rispat-Momit

    Joined:
    Feb 14, 2013
    Posts:
    266
    That's exactly what I needed :)

    I removed the limit calculations and left the rotation part which is what I needed in my project:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class IKBoneRotation : MonoBehaviour {
    6.  
    7.     public Transform Form;
    8.  
    9.     public Vector3 EulerAnglers = Vector3.zero;
    10.  
    11.     private Quaternion _startRotation = Quaternion.identity;
    12.  
    13.     void Start()
    14.     {
    15.         if (!Form)
    16.         {
    17.             Form = transform;
    18.         }
    19.  
    20.         _startRotation = Form.localRotation;
    21.     }
    22.  
    23.     void Update()
    24.     {
    25.        
    26.    
    27.  
    28.         Form.localRotation = _startRotation * Quaternion.Euler(new Vector3(EulerAnglers.x, 0f, EulerAnglers.z)) * Quaternion.Euler(new Vector3(0f, EulerAnglers.y, 0f));
    29.     }
    30. }

    Thank you so much razzraziel!

    You are a life saver!
     
    razzraziel likes this.
  5. razzraziel

    razzraziel

    Joined:
    Sep 13, 2018
    Posts:
    396
    Glad to help, good luck.