Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question How do I know when the hand finished raise up pointing the target ?

Discussion in 'Animation' started by SharonL75, Aug 19, 2020.

  1. SharonL75

    SharonL75

    Joined:
    Aug 13, 2020
    Posts:
    91
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5. using UnityEngine.UI;
    6. using System.Collections.Generic;
    7. using TMPro;
    8.  
    9. [RequireComponent(typeof(Animator))]
    10.  
    11. public class IKControl : MonoBehaviour
    12. {
    13.     public InteractableItem[] lookObj = null;
    14.     public Text text;
    15.     public float weightDamping = 1.5f;
    16.     public float maxDistance = 10f;
    17.     public bool RightHandToTarget = false;
    18.  
    19.     private Animator animator;
    20.     private InteractableItem lastPrimaryTarget;
    21.     private float lerpEndDistance = 0.1f;
    22.     private float finalLookWeight = 0;
    23.     private bool transitionToNextTarget = false;
    24.  
    25.     void Start()
    26.     {
    27.         animator = GetComponent<Animator>();
    28.     }
    29.  
    30.     // Callback for calculating IK
    31.     void OnAnimatorIK()
    32.     {
    33.         if (lookObj != null)
    34.         {
    35.             InteractableItem primaryTarget = null;
    36.             float closestLookWeight = 0;
    37.  
    38.             // Here we find the target which is closest (by angle) to the players view line
    39.             foreach (InteractableItem target in lookObj)
    40.             {
    41.                 Vector3 lookAt = target.transform.position - transform.position;
    42.                 lookAt.y = 0f;
    43.  
    44.                 // Filter out all objects that are too far away
    45.                 //if (lookAt.magnitude > maxDistance) continue;
    46.                 if (lookAt.magnitude > target.distance) continue;
    47.  
    48.                 float dotProduct = Vector3.Dot(new Vector3(transform.forward.x, 0f, transform.forward.z).normalized, lookAt.normalized);
    49.                 float lookWeight = Mathf.Clamp(dotProduct, 0f, 1f);
    50.                 if (lookWeight > 0.1f && lookWeight > closestLookWeight)
    51.                 {
    52.                     closestLookWeight = lookWeight;
    53.                     primaryTarget = target;
    54.                 }
    55.             }
    56.  
    57.             if (primaryTarget != null)
    58.             {
    59.                 if ((lastPrimaryTarget != null) && (lastPrimaryTarget != primaryTarget) && (finalLookWeight > 0f))
    60.                 {
    61.                     // Here we start a new transition because the player looks already to a target but
    62.                     // we have found another target the player should look at
    63.                     transitionToNextTarget = true;
    64.                 }
    65.             }
    66.  
    67.             // The player is in a neutral look position but has found a new target
    68.             if ((primaryTarget != null) && !transitionToNextTarget)
    69.             {
    70.                 lastPrimaryTarget = primaryTarget;
    71.                 //finalLookWeight = Mathf.Lerp(finalLookWeight, closestLookWeight, Time.deltaTime * weightDamping);
    72.                 finalLookWeight = Mathf.Lerp(finalLookWeight, 1f, Time.deltaTime * weightDamping);
    73.                 float bodyWeight = finalLookWeight * .75f;
    74.                 animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f);
    75.                 animator.SetLookAtPosition(primaryTarget.transform.position);
    76.  
    77.                 if (RightHandToTarget)
    78.                 {
    79.                     Vector3 relativePos = primaryTarget.transform.position - transform.position;
    80.                     Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
    81.                     animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
    82.                     animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
    83.                     animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.7f * closestLookWeight);
    84.                     animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
    85.                 }
    86.  
    87.                 if(animator.GetIKPositionWeight(AvatarIKGoal.RightHand) == (finalLookWeight * 0.7f * closestLookWeight))
    88.                 {
    89.                     Debug.Log("Hand at position !");
    90.                 }
    91.                 else
    92.                 {
    93.                     Debug.Log("Not at position !");
    94.                 }
    95.             }
    96.  
    97.             // Let the player smoothly look away from the last target to the neutral look position
    98.             if ((primaryTarget == null && lastPrimaryTarget != null) || transitionToNextTarget)
    99.             {
    100.                 finalLookWeight = Mathf.Lerp(finalLookWeight, 0f, Time.deltaTime * weightDamping);
    101.                 float bodyWeight = finalLookWeight * .75f;
    102.                 animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f);
    103.                 animator.SetLookAtPosition(lastPrimaryTarget.transform.position);
    104.  
    105.                 if (RightHandToTarget)
    106.                 {
    107.                     Vector3 relativePos = lastPrimaryTarget.transform.position - transform.position;
    108.                     Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
    109.                     animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
    110.                     animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
    111.                     animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.7f * closestLookWeight);
    112.                     animator.SetIKPosition(AvatarIKGoal.RightHand, lastPrimaryTarget.transform.position);
    113.                 }
    114.  
    115.                 if (finalLookWeight < lerpEndDistance)
    116.                 {
    117.                     transitionToNextTarget = false;
    118.                     finalLookWeight = 0f;
    119.                     lastPrimaryTarget = null;
    120.                 }
    121.             }
    122.  
    123.             // Show found object by the player
    124.             if (primaryTarget != null)
    125.             {
    126.                 text.text = primaryTarget.description;
    127.             }
    128.             else
    129.             {
    130.                 text.text = "";
    131.             }
    132.         }
    133.     }
    134. }
    135.  
    There are two places in the code that make the hand raise facing the target :
    In the first place I'm also trying to check when the hand finished raise up and pointing the target but the comparison never work it's always get to the else part :

    Code (csharp):
    1.  
    2. if (RightHandToTarget)
    3.                 {
    4.                     Vector3 relativePos = primaryTarget.transform.position - transform.position;
    5.                     Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
    6.                     animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
    7.                     animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
    8.                     animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.7f * closestLookWeight);
    9.                     animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
    10.                 }
    11.  
    12.                 if(animator.GetIKPositionWeight(AvatarIKGoal.RightHand) == (finalLookWeight * 0.7f * closestLookWeight))
    13.                 {
    14.                     Debug.Log("Hand at position !");
    15.                 }
    16.                 else
    17.                 {
    18.                     Debug.Log("Not at position !");
    19.                 }
    20.  
    This screenshot the right hand is pointing the cube and at this point I want to do something with the cube the player is holding :

     
  2. TimmyTheTerrible

    TimmyTheTerrible

    Joined:
    Feb 18, 2017
    Posts:
    184
    Never compare float values directly, search Google for 'floating point inaccuracies' to understand why. Instead, use Mathf.Approximately(). The function compares 2 float values and returns a boolean, true if the values you sent to it are close enough to technically be equal.
     
    SharonL75 likes this.
  3. SharonL75

    SharonL75

    Joined:
    Aug 13, 2020
    Posts:
    91
    I tried this :

    Code (csharp):
    1.  
    2. if (Mathf.Approximately(animator.GetIKPositionWeight(AvatarIKGoal.RightHand), (finalLookWeight * 0.7f * closestLookWeight)))
    3.                 {
    4.                     Debug.Log("Hand at position !");
    5.                 }
    6.                 else
    7.                 {
    8.                     Debug.Log("Not at position !");
    9.                 }
    10.  
    But the problem is that it's showing "Hand at position !" before the hand ended raise up pointing the target,
    I want it to say "Hand at position !" only when the hand ended raising up pointing the target.

    And it's never get to the else "Not at position !" even if the player is not facing the target at all.