using System; using ActionGameFramework.Helpers; using UnityEngine; namespace ActionGameFramework.Projectiles { /// /// Simple IProjectile implementation for a projectile that flies in a straight line, optionally under m_Acceleration. /// [RequireComponent(typeof(Rigidbody))] public class LinearProjectile : MonoBehaviour, IProjectile { public float acceleration; public float startSpeed; protected bool m_Fired; protected Rigidbody m_Rigidbody; public event Action fired; /// /// Fires this projectile from a designated start point to a designated world coordinate. /// /// Start point of the flight. /// Target point to fly to. public virtual void FireAtPoint(Vector3 startPoint, Vector3 targetPoint) { transform.position = startPoint; Fire(Ballistics.CalculateLinearFireVector(startPoint, targetPoint, startSpeed)); } /// /// Fires this projectile in a designated direction. /// /// Start point of the flight. /// Vector representing direction of flight. public virtual void FireInDirection(Vector3 startPoint, Vector3 fireVector) { transform.position = startPoint; // If we have no initial speed, we provide a small one to give the launch vector a baseline magnitude. if (Math.Abs(startSpeed) < float.Epsilon) { startSpeed = 0.001f; } Fire(fireVector.normalized * startSpeed); } /// /// Fires this projectile at a designated starting velocity, overriding any starting speeds. /// /// Start point of the flight. /// Vector3 representing launch velocity. public void FireAtVelocity(Vector3 startPoint, Vector3 fireVelocity) { transform.position = startPoint; startSpeed = fireVelocity.magnitude; Fire(fireVelocity); } protected virtual void Awake() { m_Rigidbody = GetComponent(); } protected virtual void Update() { if (!m_Fired) { return; } if (Math.Abs(acceleration) >= float.Epsilon) { m_Rigidbody.velocity += transform.forward * acceleration * Time.deltaTime; } } protected virtual void Fire(Vector3 firingVector) { m_Fired = true; transform.rotation = Quaternion.LookRotation(firingVector); m_Rigidbody.velocity = firingVector; if (fired != null) { fired(); } } } }