112 lines
3.3 KiB
C#
112 lines
3.3 KiB
C#
using UnityEngine;
|
|
|
|
namespace Components
|
|
{
|
|
[DisallowMultipleComponent]
|
|
public class BasicBearingComp : MonoBehaviour
|
|
{
|
|
[SerializeField] [Min(1f)] private float _rotateSpeed = 180f;
|
|
[SerializeField] [Min(0.1f)] private float _attackRange = 5f;
|
|
[SerializeField] [Min(0.1f)] private float _aimToleranceAngle = 2f;
|
|
[SerializeField] private Transform _rotateRoot;
|
|
[SerializeField] private bool _yawOnly = true;
|
|
|
|
public float RotateSpeed => _rotateSpeed;
|
|
public float AttackRange => _attackRange;
|
|
public float AimToleranceAngle => _aimToleranceAngle;
|
|
|
|
public void OnInit(float rotateSpeed, float attackRange = 5f)
|
|
{
|
|
_rotateSpeed = Mathf.Max(1f, rotateSpeed);
|
|
_attackRange = Mathf.Max(0.1f, attackRange);
|
|
}
|
|
|
|
public void OnReset()
|
|
{
|
|
_rotateSpeed = 1f;
|
|
_attackRange = 5f;
|
|
}
|
|
|
|
public bool IsTargetInRange(Transform target, Transform origin = null)
|
|
{
|
|
if (target == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Transform originTransform = origin != null ? origin : transform;
|
|
Vector3 delta = target.position - originTransform.position;
|
|
return delta.sqrMagnitude <= _attackRange * _attackRange;
|
|
}
|
|
|
|
public bool TrackTarget(Transform target, float deltaTime)
|
|
{
|
|
if (target == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Transform rotateRoot = _rotateRoot != null ? _rotateRoot : transform;
|
|
Vector3 toTarget = target.position - rotateRoot.position;
|
|
if (_yawOnly)
|
|
{
|
|
toTarget.y = 0f;
|
|
}
|
|
|
|
if (toTarget.sqrMagnitude <= Mathf.Epsilon)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Quaternion targetRotation = Quaternion.LookRotation(toTarget.normalized, Vector3.up);
|
|
float rotateAngle = _rotateSpeed * Mathf.Max(0f, deltaTime);
|
|
rotateRoot.rotation = Quaternion.RotateTowards(rotateRoot.rotation, targetRotation, rotateAngle);
|
|
return IsTargetAligned(target);
|
|
}
|
|
|
|
public bool IsTargetAligned(Transform target)
|
|
{
|
|
if (target == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Transform rotateRoot = _rotateRoot != null ? _rotateRoot : transform;
|
|
Vector3 toTarget = target.position - rotateRoot.position;
|
|
if (_yawOnly)
|
|
{
|
|
toTarget.y = 0f;
|
|
}
|
|
|
|
if (toTarget.sqrMagnitude <= Mathf.Epsilon)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
float angle = Vector3.Angle(rotateRoot.forward, toTarget.normalized);
|
|
return angle <= _aimToleranceAngle;
|
|
}
|
|
|
|
public bool TryAttack(ShooterMuzzleComp shooterMuzzleComp, Transform target, float deltaTime)
|
|
{
|
|
if (shooterMuzzleComp == null || target == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!IsTargetInRange(target))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool isAligned = TrackTarget(target, deltaTime);
|
|
if (!isAligned)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return shooterMuzzleComp.Attack(target);
|
|
}
|
|
}
|
|
}
|