using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Serialization; using Random = UnityEngine.Random; [RequireComponent(typeof(Unit))] public class AttackHandler : MonoBehaviour { [SerializeField] private float damage; [SerializeField] private float cooldown; [SerializeField] private Collider attackShape; [SerializeField] private float knockbackHorizontalForce; [SerializeField] private float knockbackVerticalForce; private float _timer; private Unit _unit; void Awake() { _unit = GetComponent(); } void Start() { // Random to avoid too much synchronicity _timer = cooldown + Random.Range(-cooldown*0.2f, cooldown*0.2f); } void Update() { _timer = _timer - Time.deltaTime; Attack(); } /// /// Launch an Attack, and return true if it's possible to attack /// see what Units are in the attackShape, apply damage and knockback to those unit if they're ennemies /// public bool Attack() { if (_timer > 0) return false; Collider[] targets = DetectTargets(); foreach (Collider target in targets) { if (!target.CompareTag("Unit")) continue; // GetComponent is expensive in performance, optimize here if it's slow Unit targetUnit = target.GetComponent(); // No friendly fire if (targetUnit.IsTeamA == _unit.IsTeamA) continue; targetUnit.Health.TakeDamage(damage); Vector3 knockbackVector = knockbackHorizontalForce * (target.transform.position - transform.position).normalized + knockbackVerticalForce * Vector3.up; targetUnit.StartCoroutine(targetUnit.Move.TakeImpulse(knockbackVector)); } _timer = cooldown + Random.Range(-cooldown*0.2f, cooldown*0.2f); return true; } private Collider[] DetectTargets() { Collider[] hitColliders; switch (attackShape) { case SphereCollider sphere: hitColliders = Physics.OverlapSphere(sphere.transform.position, sphere.radius, sphere.includeLayers); break; case BoxCollider box: hitColliders = Physics.OverlapBox(box.bounds.center, box.bounds.extents, box.transform.rotation, box.includeLayers); break; default: throw new ArgumentException("Only sphere or box are supported"); } return hitColliders; } }