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

using UnityEngine;
using System;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
using TMPro;

[RequireComponent(typeof(Animator))]

public class IKControl : MonoBehaviour
{
    public InteractableItem[] lookObj = null;
    public Text text;
    public float weightDamping = 1.5f;
    public float maxDistance = 10f;
    public bool RightHandToTarget = false;

    private Animator animator;
    private InteractableItem lastPrimaryTarget;
    private float lerpEndDistance = 0.1f;
    private float finalLookWeight = 0;
    private bool transitionToNextTarget = false;

    void Start()
    {
        animator = GetComponent<Animator>();
    }

    // Callback for calculating IK
    void OnAnimatorIK()
    {
        if (lookObj != null)
        {
            InteractableItem primaryTarget = null;
            float closestLookWeight = 0;

            // Here we find the target which is closest (by angle) to the players view line
            foreach (InteractableItem target in lookObj)
            {
                Vector3 lookAt = target.transform.position - transform.position;
                lookAt.y = 0f;

                // Filter out all objects that are too far away
                //if (lookAt.magnitude > maxDistance) continue;
                if (lookAt.magnitude > target.distance) continue;

                float dotProduct = Vector3.Dot(new Vector3(transform.forward.x, 0f, transform.forward.z).normalized, lookAt.normalized);
                float lookWeight = Mathf.Clamp(dotProduct, 0f, 1f);
                if (lookWeight > 0.1f && lookWeight > closestLookWeight)
                {
                    closestLookWeight = lookWeight;
                    primaryTarget = target;
                }
            }

            if (primaryTarget != null)
            {
                if ((lastPrimaryTarget != null) && (lastPrimaryTarget != primaryTarget) && (finalLookWeight > 0f))
                {
                    // Here we start a new transition because the player looks already to a target but
                    // we have found another target the player should look at
                    transitionToNextTarget = true;
                }
            }

            // The player is in a neutral look position but has found a new target
            if ((primaryTarget != null) && !transitionToNextTarget)
            {
                lastPrimaryTarget = primaryTarget;
                //finalLookWeight = Mathf.Lerp(finalLookWeight, closestLookWeight, Time.deltaTime * weightDamping);
                finalLookWeight = Mathf.Lerp(finalLookWeight, 1f, Time.deltaTime * weightDamping);
                float bodyWeight = finalLookWeight * .75f;
                animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f);
                animator.SetLookAtPosition(primaryTarget.transform.position);

                if (RightHandToTarget)
                {
                    Vector3 relativePos = primaryTarget.transform.position - transform.position;
                    Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
                    animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
                    animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
                    animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.7f * closestLookWeight);
                    animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
                }

                if(animator.GetIKPositionWeight(AvatarIKGoal.RightHand) == (finalLookWeight * 0.7f * closestLookWeight))
                {
                    Debug.Log("Hand at position !");
                }
                else
                {
                    Debug.Log("Not at position !");
                }
            }

            // Let the player smoothly look away from the last target to the neutral look position
            if ((primaryTarget == null && lastPrimaryTarget != null) || transitionToNextTarget)
            {
                finalLookWeight = Mathf.Lerp(finalLookWeight, 0f, Time.deltaTime * weightDamping);
                float bodyWeight = finalLookWeight * .75f;
                animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f);
                animator.SetLookAtPosition(lastPrimaryTarget.transform.position);

                if (RightHandToTarget)
                {
                    Vector3 relativePos = lastPrimaryTarget.transform.position - transform.position;
                    Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
                    animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
                    animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
                    animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.7f * closestLookWeight);
                    animator.SetIKPosition(AvatarIKGoal.RightHand, lastPrimaryTarget.transform.position);
                }

                if (finalLookWeight < lerpEndDistance)
                {
                    transitionToNextTarget = false;
                    finalLookWeight = 0f;
                    lastPrimaryTarget = null;
                }
            }

            // Show found object by the player
            if (primaryTarget != null)
            {
                text.text = primaryTarget.description;
            }
            else
            {
                text.text = "";
            }
        }
    }
}

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 :

if (RightHandToTarget)
                {
                    Vector3 relativePos = primaryTarget.transform.position - transform.position;
                    Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
                    animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
                    animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
                    animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.7f * closestLookWeight);
                    animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
                }

                if(animator.GetIKPositionWeight(AvatarIKGoal.RightHand) == (finalLookWeight * 0.7f * closestLookWeight))
                {
                    Debug.Log("Hand at position !");
                }
                else
                {
                    Debug.Log("Not at position !");
                }

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 :

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.

1 Like

I tried this :

if (Mathf.Approximately(animator.GetIKPositionWeight(AvatarIKGoal.RightHand), (finalLookWeight * 0.7f * closestLookWeight)))
                {
                    Debug.Log("Hand at position !");
                }
                else
                {
                    Debug.Log("Not at position !");
                }

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.