Hi there!
I am trying to implement next behavior : when player sees somebody he must look at him. and i can do smooth transition between two states : “player sees nothing” and “player see somebody”. but i can’t do it between “player sees somebody” and “player see another guy”. it’s has sharp transition. I’ve tried use temp for prev player, lerp for SetLookAtPosition, but it’s did not work.
#pragma warning disable 0219
#pragma warning disable 0414
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BeardedManStudios.Network;
public class RotateHeadToPlayer : MonoBehaviour
{
public List<Animator> animators = new List<Animator>();
public float lookIKWeight;
public float bodyWeight = 0.3f;
public float headWeight;
public float eyesWeight;
public float clampWeight;
public Transform lookPos;
public LayerMask layerMaskForHeadLook;
public Collider[] headLookColliders;
private PlayerMovement PM;
private Transform lookPosHead = null;
private Transform myHead = null;
[SerializeField]
private Transform tempLookPos = null;
//[SerializeField]
//private float timeToSetWeight = 3f;
// Use this for initialization
void Awake()
{
animators = GetComponentsInChildren<Animator>(true).ToList();
PM = GetComponent<PlayerMovement>();
}
// Update is called once per frame
void Update()
{
if (!PM.alive)
return;
bodyWeight = PM.defence || !PM.canAttack ? RealLerpFloat(bodyWeight, 0, 2f) : RealLerpFloat(bodyWeight, 0.3f, 2f);
FindPlayerToLook();
}
void OnAnimatorIK()
{
if (!PM.alive)
return;
if (lookPos != null)
{
lookPosHead = lookPos.GetComponent<Animator>().GetBoneTransform(HumanBodyBones.Head);
animators[0].SetLookAtWeight(lookIKWeight, bodyWeight, headWeight, eyesWeight, clampWeight);
animators[0].SetLookAtPosition(lookPosHead.position);
lookIKWeight = Mathf.Lerp(lookIKWeight, 1f, Time.deltaTime * 0.1f);
}
else
{
animators[0].SetLookAtWeight(lookIKWeight, bodyWeight, headWeight, eyesWeight, clampWeight);
lookIKWeight = Mathf.Lerp(lookIKWeight, 0, Time.deltaTime * 0.4f);
}
}
private float RealLerpFloat(float changableValue, float goalValue, float time)
{
float i = 0f;
float rate = 1f / time;
while (i < 1f)
{
i += Time.deltaTime * rate;
changableValue = Mathf.Lerp(changableValue, goalValue, i);
return changableValue;
}
return changableValue;
}
void FindPlayerToLook()
{
headLookColliders = Physics.OverlapSphere(transform.position, 20f, layerMaskForHeadLook, QueryTriggerInteraction.Ignore);
float minDistance = float.PositiveInfinity;
Transform closestPlayer = null;
foreach (var collider in headLookColliders)
{
if (collider.transform.GetInstanceID() == transform.GetInstanceID() || collider.GetComponentInParent<Animator>() == null || Vector3.Dot(transform.forward, collider.transform.root.position - transform.position) < 0)
continue;
float distance = Vector3.Distance(collider.transform.root.position, transform.position);
if (distance < minDistance)
{
minDistance = distance;
closestPlayer = collider.transform.root;
}
}
lookPos = closestPlayer != null ? closestPlayer : null;
}
}