using ActionGameFramework.Health;
using ActionGameFramework.Helpers;
using Core.Health;
using UnityEngine;
namespace ActionGameFramework.Projectiles
{
///
/// Basic override of LinearProjectile that allows them to adjust their path in-flight to intercept a designated target.
///
public class HomingLinearProjectile : LinearProjectile
{
public int leadingPrecision = 2;
public bool leadTarget;
protected Targetable m_HomingTarget;
Vector3 m_TargetVelocity;
///
/// Sets the target transform that will be homed in on once fired.
///
/// Transform of the target to home in on.
public void SetHomingTarget(Targetable target)
{
m_HomingTarget = target;
}
protected virtual void FixedUpdate()
{
if (m_HomingTarget == null)
{
return;
}
m_TargetVelocity = m_HomingTarget.velocity;
}
protected override void Update()
{
if (!m_Fired)
{
return;
}
if (m_HomingTarget == null)
{
m_Rigidbody.rotation = Quaternion.LookRotation(m_Rigidbody.velocity);
return;
}
Quaternion aimDirection = Quaternion.LookRotation(GetHeading());
m_Rigidbody.rotation = aimDirection;
m_Rigidbody.velocity = transform.forward * m_Rigidbody.velocity.magnitude;
base.Update();
}
protected Vector3 GetHeading()
{
if (m_HomingTarget == null)
{
return Vector3.zero;
}
Vector3 heading;
if (leadTarget)
{
heading = Ballistics.CalculateLinearLeadingTargetPoint(transform.position, m_HomingTarget.position,
m_TargetVelocity, m_Rigidbody.velocity.magnitude,
acceleration,
leadingPrecision) - transform.position;
}
else
{
heading = m_HomingTarget.position - transform.position;
}
return heading.normalized;
}
protected override void Fire(Vector3 firingVector)
{
if (m_HomingTarget == null)
{
Debug.LogError("Homing target has not been specified. Aborting fire.");
return;
}
m_HomingTarget.removed += OnTargetDied;
base.Fire(firingVector);
}
void OnTargetDied(DamageableBehaviour targetable)
{
targetable.removed -= OnTargetDied;
m_HomingTarget = null;
}
}
}