Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Unity IK Unexpected behavior

Discussion in 'Animation' started by Geniye, Apr 22, 2023.

  1. Geniye

    Geniye

    Joined:
    Aug 12, 2017
    Posts:
    10
    I am trying to get the hand of my model to interpolate towards 3 different points, represented by the list of control points. For whatever reason, the distance between the first point and the hand is always around 0.4f. I tried logging what the position of each object was and realized the positions were completely wrong. The position of the hand and the empty I am interpolating to are way behind the model. Even as the hand is being moved with SetIKPosition the position is not changing. The only time the position of the hand changes is when physically walk around for whatever reason. I tried doing transform.InverseTransformPoint() to see if maybe I was it was because it was a world position, however when I do that it says that both points are at 0, 0, 0 (which they sure as hell are not). I am at a complete loss I have literally no idea why it is causing this and nothing on Google or the docs has helped. Because of the position being completely wrong, Vector3.Distance always returns a value around 0.4 and therefore never progresses to the next point. Does anyone know why this is happening? The model isn't scaled in any weird way or anything everything should be right.



    What GetIKPosition() and m_rightHandObj.position says is the position of the hand
    upload_2023-4-21_17-56-49.png

    The script for the IKController of the player:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(Animator))]
    6.  
    7. public class IKControl : MonoBehaviour
    8. {
    9.     protected Animator m_animator;
    10.  
    11.     [SerializeField] private bool m_isIkActive = false;
    12.     [SerializeField] private Transform m_rightHandObj = null;
    13.     [SerializeField] private float m_interpolationSpeed = 2.5f;
    14.     [SerializeField] private Transform m_rightHand;
    15.  
    16.     [Space(10)]
    17.     [Header("CONTROL POINTS (ORDER = ORDER OF EXECUTION)")]
    18.     [SerializeField] private IKControlPoint[] m_controlPoints;
    19.  
    20.     private Vector3 m_currentHandPosition = new Vector3();
    21.     private Quaternion m_currentHandRotation = new Quaternion();
    22.  
    23.     private float startTime;
    24.     private float distanceBtwPoints;
    25.  
    26.     private bool hasStarted = false;
    27.     private bool hasArrived = false;
    28.     private bool hasFinished = false;
    29.     private int pullingOutControlIndex = 0;
    30.  
    31.     /*
    32.      * current -> side, side -> back, back -> side, side -> mouth
    33.     */
    34.  
    35.     private void Start()
    36.     {
    37.         m_animator = GetComponent<Animator>();
    38.     }
    39.  
    40.     public void BeginPullOutAnimation()
    41.     {
    42.         if (!hasStarted)
    43.         {
    44.             hasStarted = true;
    45.             startTime = Time.time;
    46.             distanceBtwPoints = Vector3.Distance(m_rightHand.position, m_controlPoints[0].transform.position);
    47.             Debug.Log(distanceBtwPoints);
    48.         }
    49.     }
    50.  
    51.     private void OnAnimatorIK(int layerIndex)
    52.     {
    53.         if (!m_animator) return;
    54.  
    55.         if (hasStarted && !hasFinished)
    56.         {
    57.             Debug.Log("RUNNING ANIMATION");
    58.             PullOutAnimation();
    59.         }
    60.         else
    61.         {
    62.             m_animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
    63.             m_animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);
    64.  
    65.  
    66.         }
    67.     }
    68.  
    69.     private void PullOutAnimation()
    70.     {
    71.         if (!hasArrived)
    72.         {
    73.             m_currentHandPosition = m_animator.GetIKPosition(AvatarIKGoal.RightHand);
    74.             m_currentHandRotation = m_animator.GetIKRotation(AvatarIKGoal.RightHand);
    75.  
    76.             //Debug.Log("TARGET CONTROL POINT: " + m_controlPoints[pullingOutControlIndex].transform.position + "\nCURRENT HAND POSITION: " + m_currentHandPosition +
    77.             //   "\nDISTANCE BTW: " + Vector3.Distance(m_rightHand.position, m_controlPoints[pullingOutControlIndex].transform.position));
    78.  
    79.             Debug.Log(m_rightHand.position + "\n" + m_controlPoints[pullingOutControlIndex].transform.position);
    80.  
    81.             if (Vector3.Distance(m_rightHand.position, m_controlPoints[pullingOutControlIndex].transform.position) < 0.1f)
    82.             {
    83.                 Debug.Log("ARRIVED");
    84.                 hasArrived = true;
    85.             }
    86.             else
    87.             {
    88.                 m_animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
    89.                 m_animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
    90.  
    91.                 float distanceCovered = (Time.time - startTime) * m_interpolationSpeed;
    92.                 float fractionOfDistance = distanceCovered / distanceBtwPoints;
    93.  
    94.                 m_animator.SetIKPosition(AvatarIKGoal.RightHand, Vector3.Lerp(m_currentHandPosition, m_controlPoints[pullingOutControlIndex].transform.position, fractionOfDistance));
    95.                 m_animator.SetIKRotation(AvatarIKGoal.RightHand, Quaternion.Lerp(m_currentHandRotation, m_controlPoints[pullingOutControlIndex].transform.rotation, fractionOfDistance));
    96.             }
    97.         }
    98.         else
    99.         {
    100.             pullingOutControlIndex++;
    101.             Debug.Log(pullingOutControlIndex);
    102.             if (pullingOutControlIndex <= m_controlPoints.Length - 1)
    103.             {
    104.                 startTime = Time.time;
    105.                 distanceBtwPoints = Vector3.Distance(m_rightHand.position, m_controlPoints[pullingOutControlIndex].transform.position);
    106.  
    107.                 if (m_controlPoints[pullingOutControlIndex].typeOfControlPoint == IKControlPoint.ControlPointType.Spawn)
    108.                 {
    109.                     // SPAWN OBJECT IN HAND
    110.                 }
    111.  
    112.                 hasArrived = false;
    113.             }
    114.             else
    115.             {
    116.                 hasFinished = true;
    117.                 //hasStarted = false;
    118.             }
    119.         }
    120.     }
    121.  
    122. }
    123.  
     

    Attached Files:

    Last edited: Apr 22, 2023
  2. Geniye

    Geniye

    Joined:
    Aug 12, 2017
    Posts:
    10
    please
     
  3. Geniye

    Geniye

    Joined:
    Aug 12, 2017
    Posts:
    10
    figured it out and im not saying what i did to fix it