in the list lookObjects i added to it two cubes. each cube move around the player in another speed.
the player is looking at only the second cube in the list but never the first one the fastest one.
what i’m trying to do is that the player will look at the closest object in the list depending if one of the objects is behind the player or in front the player sight.
it’s working fine with one object but i want it to be able to switch between multiple objects depending on closest one and if in the player sight line.
I tried to change the foreach to make it a bigger foreach loop around all the code but it didn’t work.
The player is looking at only the last object in the list.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
[RequireComponent(typeof(Animator))]
public class IKTests : MonoBehaviour
{
public Transform finger;
public List<Transform> lookObjects = new List<Transform>();
public float weightDamping = 1.5f;
private Animator animator;
private Transform lastPrimaryTarget;
private float lerpEndDistance = 0.1f;
private float finalLookWeight = 0;
private bool transitionToNextTarget = false;
void Start()
{
animator = GetComponent<Animator>();
}
private void Update()
{
}
private void OnDrawGizmos()
{
if (finger != null && lookObjects != null && lookObjects.Count > 0)
{
Gizmos.color = Color.green;
Gizmos.DrawLine(finger.position, lookObjects[0].position);
}
}
// Callback for calculating IK
void OnAnimatorIK()
{
if (lookObjects != null)
{
Transform primaryTarget = null;
float closestLookWeight = 0;
// Here we find the target which is closest (by angle) to the players view line
foreach (Transform target in lookObjects)
{
Vector3 lookAt = target.position - transform.position;
lookAt.y = 0f;
float dotProduct = Vector3.Dot(new Vector3(transform.forward.x, 0f, transform.forward.z).normalized, lookAt.normalized);
float lookWeight = dotProduct;
closestLookWeight = float.MinValue;
if (lookWeight > closestLookWeight)
{
primaryTarget = target;
}
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKPosition(AvatarIKGoal.RightHand, target.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, target.rotation);
}
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);
float bodyWeight = finalLookWeight * .75f;
animator.SetLookAtWeight(0.5f, 0.5f, 1f);//finalLookWeight, bodyWeight, 1f);
animator.SetLookAtPosition(primaryTarget.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(0.5f, 0.5f, 1f);//finalLookWeight, bodyWeight, 1f);
animator.SetLookAtPosition(lastPrimaryTarget.position);
if (finalLookWeight < lerpEndDistance)
{
transitionToNextTarget = false;
finalLookWeight = 0f;
lastPrimaryTarget = null;
}
}
}
}
}