Firstborn/Assets/RPG Creation Kit/Scripts/AI/AI Scripts/AILookAt.cs

166 lines
3.5 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPGCreationKit;
using System;
using RPGCreationKit.Player;
namespace RPGCreationKit.AI
{
/// <summary>
/// Allows NPCs to look at target with the head and body
/// </summary>
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);
}
}
/// <summary>
/// Sets a Target, this will not affect anything if the AI is currently looking in forceTarget mode.
/// </summary>
/// <param name="_target"></param>
public void SetTarget(Transform _target)
{
Debug.Log("SetTarget("+_target.gameObject.name+")");
if (_target.CompareTag("Player"))
_target = RckPlayer.instance.entityFocusPart;
if (forceTarget)
return;
if (target != null)
previousTarget = target;
target = _target;
shouldLook = true;
}
/// <summary>
/// Clears the target.
/// </summary>
public void ClearTarget()
{
shouldLook = false;
}
/// <summary>
/// Make the AI look at the providen target, no matter what.
/// </summary>
/// <param name="_target"></param>
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;
}
/// <summary>
/// Releases the AI, allowing it to look at whatever it wants/prefers.
/// </summary>
public void StopForcingLookAtTarget()
{
shouldLook = false;
forceTarget = false;
}
}
}