using UnityEngine;
using System;
using System.Collections;
using UnityEngine.SocialPlatforms;
using UnityEditor.Animations;
using UnityEngine.UI;
using System.Collections.Generic;
[RequireComponent(typeof(Animator))]
public class IKControl : MonoBehaviour
{
public List<Transform> targets = new List<Transform>();
public Transform lookObj = null;
public Transform head = null;
public float finalLookWeight;
public float weightDamping = 1.5f;
public float playerSpeedRot;
public bool rotatePlayer = false;
public GameObject text;
protected Animator animator;
private float inputMovement;
private Text textC;
void Start()
{
animator = GetComponent<Animator>();
textC = text.GetComponent<Text>();
}
//a callback for calculating IK
void OnAnimatorIK()
{
var ClosestTarget = GetClosestTarget(targets, transform);
lookObj = ClosestTarget;
Vector3 flattenedLookAtVector = Vector3.ProjectOnPlane(lookObj.position - transform.position, transform.up);
float dotProduct = Vector3.Dot(transform.forward, flattenedLookAtVector);
float lookWeight = Mathf.Clamp(dotProduct, 0f, 1f);
finalLookWeight = Mathf.Lerp(finalLookWeight, lookWeight, Time.deltaTime * weightDamping);
float bodyWeight = finalLookWeight * .5f;
animator.SetLookAtWeight(finalLookWeight, bodyWeight);
animator.SetLookAtPosition(lookObj.position);
if (rotatePlayer == true)
{
var lookPos = lookObj.position - transform.position;
lookPos.y = 0;
var rotation = Quaternion.LookRotation(lookPos);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation,
Time.deltaTime * playerSpeedRot);
}
}
private void FixedUpdate()
{
TargetHit();
}
private void TargetHit()
{
int layerMask = 1 << 8;
RaycastHit hit;
// Does the ray intersect any objects excluding the player layer
if (Physics.Raycast(head.position, head.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
{
text.SetActive(true);
textC.text = "Hit !" + hit.transform.name;
}
else
{
textC.text = "Nothing to hit !";
}
}
private Transform GetClosestTarget(List<Transform> targets, Transform fromThis)
{
Transform bestTarget = null;
float closestDistanceSqr = Mathf.Infinity;
Vector3 currentPosition = fromThis.position;
foreach (Transform potentialTarget in targets)
{
Vector3 directionToTarget = potentialTarget.position - currentPosition;
float dSqrToTarget = directionToTarget.sqrMagnitude;
if (dSqrToTarget < closestDistanceSqr)
{
closestDistanceSqr = dSqrToTarget;
bestTarget = potentialTarget;
}
}
return bestTarget;
}
}
The script is working great.
My question is if using the callback OnAnimatorIK and FixedUpdate in the same script is fine ?
I tested it and if I’m calling the method TargetHit from inside the callback OnAnimatorIK it’s not working. but if I’m calling the TargetHit from inside the FixedUpdate it’s working. It’s more a knowledge question then a problem since it’s working fine.