Files
beyond/Assets/ThirdParty/Invector-3rdPersonController/Basic Locomotion/Scripts/Generic/Utils/vRotateToTarget.cs
2024-11-20 15:21:28 +01:00

124 lines
4.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace Invector
{
[vClassHeader("Rotate To Target")]
public class vRotateToTarget : vMonoBehaviour
{
public Transform targetTransform;
[FormerlySerializedAs("angleRoot")]
public Transform angleRootH;
public Transform rotatorH;
public Transform angleRootV;
[FormerlySerializedAs("rotator")]
public Transform rotatorV;
public bool rotateH;
public bool rotateV;
public float rotationSpeedInAngle;
public float rotationSpeedOutAngle;
[Range(0.0f, 180.0f)]
public float maxAngleVertical = 60.0f;
[Range(0.0f, 180.0f)]
public float maxAngleHorizontal = 60.0f;
[Range(0.0f, 180.0f)]
public float angleToReachTarget = 45f;
public UnityEngine.Events.UnityEvent onEnterAngle;
public UnityEngine.Events.UnityEvent onStayAngle;
public UnityEngine.Events.UnityEvent onExitAngle;
public bool targetIsInAngleRange { protected set; get; }
protected float angleH;
protected float angleV;
protected virtual void Start()
{
if (angleRootH == null) angleRootH = transform;
if (angleRootV == null) angleRootV = transform;
}
protected virtual void Update()
{
if (!angleRootH || !rotatorV ) return;
Transform target = targetTransform;
if (rotatorV)
angleV = rotatorV.localEulerAngles.x;
if(rotatorH)
angleH = rotatorH.localEulerAngles.y;
if (target)
{
Vector3 targetDirV = target.position - angleRootV.position;
Vector3 targetDirH = target.position - angleRootH.position;
float _targetAngleV = angleRootV.forward.AngleFormOtherDirection(targetDirV.normalized).x;
float _targetAngleH = angleRootH.forward.AngleFormOtherDirection(targetDirH.normalized).y;
bool _isInAngle = Mathf.Abs(_targetAngleV) <= maxAngleVertical && Mathf.Abs(_targetAngleH) <= maxAngleHorizontal;
if(_isInAngle!=targetIsInAngleRange)
{
if (_isInAngle) onEnterAngle.Invoke();
else onExitAngle.Invoke();
targetIsInAngleRange = _isInAngle;
}
if (targetIsInAngleRange)
{
onStayAngle.Invoke();
angleV = Mathf.LerpAngle(angleV, _targetAngleV, rotationSpeedInAngle * Time.deltaTime);
angleH = Mathf.LerpAngle(angleH, _targetAngleH, rotationSpeedInAngle * Time.deltaTime);
}
else
{
angleV = Mathf.LerpAngle(angleV, 0, rotationSpeedOutAngle * Time.deltaTime);
angleH = Mathf.LerpAngle(angleH, 0, rotationSpeedOutAngle * Time.deltaTime);
}
}
else
{
if(targetIsInAngleRange)
{
onExitAngle.Invoke();
targetIsInAngleRange = false;
}
if(rotatorV.localEulerAngles.magnitude>0)
{
angleV = Mathf.LerpAngle(angleV, 0, rotationSpeedOutAngle * Time.deltaTime);
angleH = Mathf.LerpAngle(angleH, 0, rotationSpeedOutAngle * Time.deltaTime);
}
}
if (rotateV && rotateV)
{
Vector3 eulerV = rotatorV.localEulerAngles;
eulerV.x = angleV;
rotatorV.localEulerAngles = eulerV;
}
if (rotateH && rotatorH)
{
Vector3 eulerH = rotatorH.localEulerAngles;
eulerH.y = angleH;
rotatorH.localEulerAngles = eulerH;
}
}
public void SetTarget(Transform target)
{
targetTransform = target;
}
public void ClearTarget()
{
targetTransform = null;
}
}
}