using Pausable; using UnityEngine; using UnityEngine.Events; namespace AI { public class ShootingEnemyAI : MonoBehaviour, IPausable { [SerializeField] protected float attacksPerSecond = 1f; [SerializeField] protected float attackRange = 5f; [SerializeField] protected float timeForProjectileToHit = .25f; protected float cooldownPerShoot = 0f; protected float remainingCooldown = 0f; private float attackRangeSquared = 5f; private Transform target = null; private bool canShoot => (target.transform.position - transform.position).sqrMagnitude < attackRangeSquared && target != null; public UnityEvent OnShoot { get; protected set; } = null; #region IPausable public bool IsPaused { get; protected set; } = false; public virtual void Pause() => IsPaused = true; public virtual void Resume() => IsPaused = false; #endregion protected void Awake() { cooldownPerShoot = 1f / attacksPerSecond; attackRangeSquared = attackRange * attackRange; OnShoot = new UnityEvent(); UpdateTarget(FindObjectOfType()?.transform); } protected void Update() { remainingCooldown -= Time.deltaTime; if (remainingCooldown <= 0f && canShoot) Shoot(); } protected void Shoot() { Projectile projectile = ProjectilePool.Instance.Get(); projectile.transform.position = transform.position; Vector3 velocity = GetVelocityForProjectile(timeForProjectileToHit); RaycastHit2D raycastHit2D = Physics2D.Raycast(transform.position, target.position - transform.position, attackRange); if (raycastHit2D.transform != target) velocity = GetVelocityForProjectile(timeForProjectileToHit * 2); projectile.SetVelocity(velocity); remainingCooldown = cooldownPerShoot; OnShoot?.Invoke(); } private Vector3 GetVelocityForProjectile(float time) { Vector3 vector3 = target.position - transform.position; vector3.z = 0f; vector3.y -= (Physics2D.gravity.y / 2) * (time * time); vector3 /= time; return vector3; } public void UpdateTarget(Transform transform) => target = transform; private void OnDrawGizmosSelected() { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, 0.125f); Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, attackRange); } } }