A bit long but all connected. I can add a short video clip that shows the problem when the hand is outstretched or some screenshots.
The Animator component is no the Player, not the transform(NAVI) so I don't want to disable/enable the Animator on the Player.
If the player's hand is down in its natural state, the transform moves to the player's hand and smoothly becomes a child of the hand. but if the hand is up pointing the transform then the movement is not smooth anymore.
The player has these components:
Animator , Rigidbody , Capsule collider , Third Person Character , Third Person User Control , Ik Control script that use the player rig to change the hand state position using weight.
This script is moving the transform to the player hand :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NaviManager : MonoBehaviour
{
public enum TransitionState
{
None,
MovingTowards,
Transferring
}
public Transform player;
public Transform carte;
public Animation anim;
public Transform destinationTransform;
public float speed;
public float distanceToStop;
public float lerpTime;
public string childState;
private GameObject rig_f_middle;
private Transform originTransform;
private float timer;
private bool openonce = false;
private TransitionState state = TransitionState.MovingTowards;
private InteractableItem naviInteractableItem;
void Start()
{
rig_f_middle = GameObject.Find("rig_f_middle.02.R");
destinationTransform = rig_f_middle.transform;
naviInteractableItem = GetComponent<InteractableItem>();
}
void Update()
{
var dist = Vector3.Distance(carte.position, player.position);
if (dist < 1.7f)
{
if (openonce == false)
{
anim.Play("Crate_Open");
openonce = true;
}
if (openonce)
{
switch (state)
{
case TransitionState.MovingTowards:
var v = rig_f_middle.transform.position - transform.position;
if (v.magnitude < 0.001f)
{
state = TransitionState.Transferring;
originTransform = rig_f_middle.transform;
timer = 0;
return;
}
Vector3 moveDir = v.normalized;
transform.position += moveDir * speed * Time.deltaTime;
break;
case TransitionState.Transferring:
timer += Time.deltaTime;
this.transform.position = Vector3.Lerp(originTransform.position, destinationTransform.position, timer);
if (timer >= 1.0f)
{
this.transform.parent = destinationTransform;
state = TransitionState.None;
if (naviInteractableItem != null)
{
naviInteractableItem.distance = 0f;
}
this.enabled = false;
return;
}
break;
default:
this.enabled = false;
return;
}
}
}
}
}
This part of the script from the Ik Control is changing the hand state pointing towards a target :
if ((primaryTarget != null) && !transitionToNextTarget)
{
if (primaryTarget.IsAnyAction())//.interactableMode == InteractableItem.InteractableMode.ActionWithoutThrow)
{
RightHandToTarget = true;
}
lastPrimaryTarget = primaryTarget;
finalLookWeight = Mathf.Lerp(finalLookWeight, 1f, Time.deltaTime * weightDamping);
float bodyWeight = finalLookWeight * .1f;
animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f);
animator.SetLookAtPosition(primaryTarget.transform.position);
if (RightHandToTarget && primaryTarget.IsAnyAction())
{
Vector3 relativePos = primaryTarget.transform.position - transform.position;
Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up);
if (primaryTarget.interactableMode == InteractableItem.InteractableMode.ActionWithoutThrow)
{
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 1f * closestLookWeight);
animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
}
if (primaryTarget.interactableMode == InteractableItem.InteractableMode.Action)
{
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight);
animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget);
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight * 0.1f * closestLookWeight);
animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
}
// -> new code block
if (finalLookWeight > 0.95f) // here you can play with a value between 0.95f -> 1.0f
{
if (primaryTarget.interactableMode == InteractableItem.InteractableMode.Action
&& hasSent == false)
{
target = primaryTarget;
toTarget = true;
hasSent = true;
primaryTarget.description = "";
// Here I need to find where to make hasSent false again.
}
}
else
{
hasSent = false;
}
if (finalLookWeight > 0.9f)
{
handFinishedMove = true;
}
}
}
This is a link for the full IK Control script it's a bit long :