From 823b1f5da8c6213424966f0536a9121614cceb7b Mon Sep 17 00:00:00 2001 From: craftwill Date: Wed, 30 Oct 2024 11:22:29 -0400 Subject: [PATCH] Fixed allies sometimes not attacking by redoing the detection code --- Assets/Scripts/Detection.cs | 201 +++++++++++++++++++----------------- Assets/Scripts/Entity.cs | 2 +- Assets/Scripts/Root.cs | 2 + 3 files changed, 111 insertions(+), 94 deletions(-) diff --git a/Assets/Scripts/Detection.cs b/Assets/Scripts/Detection.cs index 5c1339f..0dc117c 100644 --- a/Assets/Scripts/Detection.cs +++ b/Assets/Scripts/Detection.cs @@ -4,26 +4,109 @@ using UnityEngine; public class Detection : MonoBehaviour { - private Vector2 detectionRange; - private BoxCollider2D _collider; - public Rect DetectionRectangle - { - get - { - var coll = GetComponent(); - var rect = new Rect(coll.offset, coll.size); - return rect; - } - } - [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()); } - void ResizeCollider() + + // 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) + { + _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; @@ -38,86 +121,9 @@ public class Detection : MonoBehaviour offset.x = Mathf.Sign(offset.x) * size.x / 2; _collider.offset = offset; } - //If it's a projectile damage > 0 - private int _projectileDamage = 0; - private float _distanceMin = 100f; + #endregion - protected virtual void Update() - { - ResizeCollider(); - } - - void OnTriggerEnter2D(Collider2D other) - { - //Projectiles detection + damage deal - if(_entityLinked != null) { - if(_projectileDamage > 0 && other.gameObject.GetComponent() == _entityLinked) { - - _entityLinked.Hit(_projectileDamage); - //Kill if no hp - if(other.gameObject.GetComponent().Hp <= 0) { - other.gameObject.GetComponent().Death(); - } - - _entityLinked = null; - - } - } - - } - - void OnTriggerStay2D(Collider2D other) - { - if(_entityLinked != null && _projectileDamage == 0) { - - //Detect the enemy and inform the Ally - if (other.gameObject.tag == "Opponent" && _entityLinked.gameObject.tag == "Ally") { - if(other.gameObject.transform.position.x <= _distanceMin) { - _distanceMin = other.gameObject.transform.position.x; - _entityLinked.IsEnemyDetected = true; - _entityLinked.Enemy = other.gameObject.GetComponent(); - } - } - - //Detect the enemy and inform the Opponent - if (other.gameObject.tag == "Ally" && _entityLinked.gameObject.tag == "Opponent" ) { - if(other.gameObject.transform.position.x <= _distanceMin) { - _distanceMin = other.gameObject.transform.position.x; - _entityLinked.IsEnemyDetected = true; - _entityLinked.Enemy = other.gameObject.GetComponent(); - } - } - - if(_entityLinked.Enemy == null && _distanceMin != 100f) { - _distanceMin = 100f; - } - } - - - - } - - void OnTriggerExit2D(Collider2D other) - { - if(_entityLinked != null) { - if(_projectileDamage == 0) { - if ((other.gameObject.tag == "Opponent" && _entityLinked is Ally) || (other.gameObject.tag == "Ally" && _entityLinked is Opponent)) { - _entityLinked.IsEnemyDetected = false; - StartCoroutine(ToggleCollider()); - } - } - } - - } - - IEnumerator ToggleCollider() - { - _collider.enabled = false; - yield return null; - _collider.enabled = true; - } - - //Getter and Setter + // Getter and Setter public Entity EntityLinked { get { return _entityLinked; } @@ -129,5 +135,14 @@ public class Detection : MonoBehaviour get { return _projectileDamage; } set { _projectileDamage = value; } } - + + public Rect DetectionRectangle + { + get + { + var coll = GetComponent(); + var rect = new Rect(coll.offset, coll.size); + return rect; + } + } } diff --git a/Assets/Scripts/Entity.cs b/Assets/Scripts/Entity.cs index 5a555ff..9ee431a 100644 --- a/Assets/Scripts/Entity.cs +++ b/Assets/Scripts/Entity.cs @@ -26,6 +26,7 @@ public abstract class Entity : LevelObject //Enemy Spotted private bool _isEnemyDetected = false; + [SerializeField] private Entity _enemy; //Methods @@ -74,7 +75,6 @@ public abstract class Entity : LevelObject //When hit : get damage and start a flash of light public void Hit(int damage) { - _hp-=damage; _lifeBar.value = _hp / (float)_maxHp; diff --git a/Assets/Scripts/Root.cs b/Assets/Scripts/Root.cs index 083f60a..338cc8f 100644 --- a/Assets/Scripts/Root.cs +++ b/Assets/Scripts/Root.cs @@ -14,6 +14,8 @@ public class Root : MonoBehaviour public void Attack() { + if (_entity == null || _entity.Enemy == null) return; + _entity.Enemy.Hit(_entity.AttackDamage); if(_entity.Enemy.Hp <= 0) {