124 lines
4.2 KiB
C#
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;
|
|
}
|
|
}
|
|
} |