using System.Collections; using System.Collections.Generic; using UnityEngine; public class Detection : MonoBehaviour { [SerializeField] private Entity _entityLinked; private Vector2 detectionRange; private BoxCollider2D _collider; // List to store all detected objects trough triggerStay2D private List detectedEntities = new List(); // If it's a projectile damage > 0 private int _projectileDamage = 0; protected virtual void Start() { _collider = GetComponent(); detectionRange = _collider.size; StartCoroutine(C_DetectCoroutine()); } // Looped detection every 'delay' amount private IEnumerator C_DetectCoroutine() { // Can happen if unit dies if (_entityLinked == null) yield break; ResizeCollider(); // Remove objects that are null detectedEntities.RemoveAll(obj => !obj); Entity closest = GetClosest(); if (closest != null) { _entityLinked.IsEnemyDetected = true; _entityLinked.Enemy = closest; } else { _entityLinked.IsEnemyDetected = false; _entityLinked.Enemy = null; } yield return new WaitForSeconds(0.05f); StartCoroutine(C_DetectCoroutine()); } private void OnTriggerEnter2D(Collider2D other) { if (_entityLinked == null) return; // Projectiles detection + deal dmg Entity otherEntity = other.gameObject.GetComponent(); if (otherEntity == _entityLinked) { GhostOpponent isGhost = EntityLinked.gameObject.GetComponent(); if (isGhost != null) { if(!isGhost.dodgedProjectile()) _entityLinked.Hit(_projectileDamage); } else _entityLinked.Hit(_projectileDamage); // Kill if no hp if (otherEntity.Hp <= 0) { otherEntity.Death(); } _entityLinked = null; } } private void OnTriggerStay2D(Collider2D other) { if(_entityLinked != null && _projectileDamage == 0) { GameObject detected = other.gameObject; string tagToCheck = (_entityLinked.gameObject.tag == "Ally") ? "Opponent" : "Ally"; if (detected.tag == tagToCheck) { Entity entity = other.GetComponent(); if (!detectedEntities.Contains(entity)) { detectedEntities.Add(entity); } } } } public Entity GetClosest() { Entity closest = null; float closestDistance = Mathf.Infinity; Vector3 currentPosition = transform.position; foreach (Entity entity in detectedEntities) { if (entity == null) continue; float distance = Vector3.Distance(currentPosition, entity.transform.position); if (distance < closestDistance) { closestDistance = distance; closest = entity; } } return closest; } #region Resize private void ResizeCollider() { if (!EntityLinked) return; var multiplier = EntityLinked.RangeMultiplier; var size = _collider.size; size.x = detectionRange.x * multiplier.x; size.y = detectionRange.y * multiplier.y; _collider.size = size; var offset = _collider.offset; if (offset == Vector2.zero) return; offset.x = Mathf.Sign(offset.x) * size.x / 2; _collider.offset = offset; } #endregion // Getter and Setter public Entity EntityLinked { get { return _entityLinked; } set { _entityLinked = value; } } public int ProjectileDamage { get { return _projectileDamage; } set { _projectileDamage = value; } } public Rect DetectionRectangle { get { var coll = GetComponent(); var rect = new Rect(coll.offset, coll.size); return rect; } } }