using GameDev.CoreSystems; using UnityEngine; using UnityEngine.Serialization; namespace AsteroidGame.Entities { public class Targeter : MonoBehaviour { [SerializeField] private SoTargeterConfig _targeterConfig; [SerializeField] private float _range; [SerializeField] private SoTargeterConfig.TargetStrategy _targetStrategy; [FormerlySerializedAs("_activeEntities")] [SerializeField] private SoTargetableRuntimeSet _activeTargetable; [SerializeField] private Targetable _targeterParent; [field: SerializeField] public Targetable TargetEntity { get; set; } private void OnEnable() { SetConfig(_targeterConfig); } public void SetParent(Targetable newParent) => _targeterParent = newParent; public void SetConfig(SoTargeterConfig config) { _range = config._maxRange; _targetStrategy = config._selectedTargetStrategy; _activeTargetable = config._activeEntities; } public Targetable GetTarget() { return TargetEntity; } public bool FindTarget() { var currentBestValue = Mathf.Infinity; var targetFound = false; foreach (var targetEntity in _activeTargetable) { var distanceToTarget = Vector3.Magnitude(targetEntity.GetCenterPosition() - _targeterParent.GetCenterPosition()); var withinRange = distanceToTarget < _range; if (withinRange) { switch (_targetStrategy) { case SoTargeterConfig.TargetStrategy.LowestRange: { var isClosest = distanceToTarget < currentBestValue; if (isClosest) { targetFound = true; currentBestValue = distanceToTarget; TargetEntity = targetEntity; } break; } case SoTargeterConfig.TargetStrategy.LowestHealth: { float enemyHealth = targetEntity.Damageable.GetCurrentHealth(); var isLowestHealth = enemyHealth < currentBestValue; if (isLowestHealth) { targetFound = true; currentBestValue = enemyHealth; TargetEntity = targetEntity; } break; } } } } return targetFound; } } }