Re-added the "GhostOpponent" class to determine if the enemy is capable of dodging projectiles.
155 lines
4.2 KiB
C#
155 lines
4.2 KiB
C#
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<Entity> detectedEntities = new List<Entity>();
|
|
|
|
// If it's a projectile damage > 0
|
|
private int _projectileDamage = 0;
|
|
|
|
protected virtual void Start()
|
|
{
|
|
_collider = GetComponent<BoxCollider2D>();
|
|
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<Entity>();
|
|
if (otherEntity == _entityLinked)
|
|
{
|
|
GhostOpponent isGhost = EntityLinked.gameObject.GetComponent<GhostOpponent>();
|
|
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<Entity>();
|
|
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<BoxCollider2D>();
|
|
var rect = new Rect(coll.offset, coll.size);
|
|
return rect;
|
|
}
|
|
}
|
|
}
|