using System.Collections; using System.Collections.Generic; using UnityEngine; using RPGCreationKit; using System; using RPGCreationKit.Player; namespace RPGCreationKit.AI { /// /// Allows NPCs to look at target with the head and body /// public class AILookAt : MonoBehaviour { public bool isEnabled = true; // Force Target is used to force the AI to look at something, like in a conversation we always want the AI to look at the interlocutor public bool forceTarget = false; [SerializeField] Animator animator; [Space(5)] // Target determines the target to look at public Transform target; // Previous Target is used to restore the original view without jittering [HideInInspector] public Transform previousTarget; [Space(5)] public float rotSpeed = 1.0f; public bool bodyWeight = true; private float tTime = 0f; public bool shouldLook = false; public bool IsLookingAtSomeone { get { return shouldLook; } } private void Update() { if (!isEnabled) return; // Updates the tTime to manage the weight of which the limbs are affected in the rotation if (shouldLook) { tTime += rotSpeed * Time.deltaTime; tTime = Mathf.Clamp01(tTime); } else { tTime -= rotSpeed * Time.deltaTime; tTime = Mathf.Clamp01(tTime); } } private void OnAnimatorIK(int layerIndex) { if (!isEnabled) return; if (target != null) { if(bodyWeight) animator.SetLookAtWeight(tTime, tTime / 5, tTime, tTime, .7f); else animator.SetLookAtWeight(tTime, 0, tTime, tTime, .7f); animator.SetLookAtPosition(target.position); } } /// /// Sets a Target, this will not affect anything if the AI is currently looking in forceTarget mode. /// /// public void SetTarget(Transform _target) { if (_target.CompareTag("Player")) _target = RckPlayer.instance.entityFocusPart; if (forceTarget) return; if (target != null) previousTarget = target; target = _target; shouldLook = true; } /// /// Clears the target. /// public void ClearTarget() { shouldLook = false; } /// /// Make the AI look at the providen target, no matter what. /// /// public void ForceToLookAtTarget(Transform _target) { if (_target.CompareTag("Player")) _target = RckPlayer.instance.entityFocusPart; if (IsLookingAtSomeone == true) { forceTarget = true; if (target != null &&target.CompareTag("Player") && _target.CompareTag("Player")) return; // Not if its the same pp if (_target != target) { // If should look is true we have to debunk ttime and when it reaches 0 we set the new target and force StartCoroutine(ForceLookTask(_target)); } return; } target = _target; shouldLook = true; forceTarget = true; if (target.CompareTag("Player")) target = RckPlayer.instance.entityFocusPart; } public IEnumerator ForceLookTask(Transform _target) { shouldLook = false; // wait to debunk while(tTime >= 0.1f) { yield return null; } target = _target; shouldLook = true; forceTarget = true; } /// /// Releases the AI, allowing it to look at whatever it wants/prefers. /// public void StopForcingLookAtTarget() { shouldLook = false; forceTarget = false; } } }