using Code.Gameplay.Character.Core; using UnityEngine; using Code.Gameplay.Core; using Code.Gameplay.Character.Stats; using Code.Gameplay.Weapons; namespace Code.Gameplay.Enemy { public class SimpleEnemy : MonoBehaviour, IDamageable { [SerializeField] private HealthSystem healthSystem; [SerializeField] private WeaponBase weapon; [SerializeField] private Transform firePoint; [SerializeField] private Transform target; [SerializeField] private float moveSpeed = 3f; [SerializeField] private float rotationSpeed = 5f; [SerializeField] private float detectionRange = 20f; [SerializeField] private float attackRange = 15f; [SerializeField] private float stopDistance = 5f; [SerializeField] private float attackCooldown = 1f; [SerializeField] private LayerMask obstacleMask; private float lastAttackTime; private bool isAttacking; private CharacterController characterController; public bool IsAlive => healthSystem != null && healthSystem.IsAlive; private void Awake() { characterController = GetComponent(); if (characterController == null) characterController = gameObject.AddComponent(); if (healthSystem == null) healthSystem = GetComponent(); } private void Start() { if (healthSystem != null) { healthSystem.OnDied += HandleDeath; } if (target != null) return; var player = FindFirstObjectByType(); if (player != null) target = player.transform; } private void Update() { if (!IsAlive || target == null) return; var distanceToTarget = Vector3.Distance(transform.position, target.position); if (!(distanceToTarget <= detectionRange)) return; RotateTowardsTarget(); if (distanceToTarget <= attackRange) { Attack(); if (distanceToTarget < stopDistance) { MoveAway(); } } else { MoveTowardsTarget(); } } private void RotateTowardsTarget() { var direction = (target.position - transform.position).normalized; direction.y = 0; var lookRotation = Quaternion.LookRotation(direction); transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed); } private void MoveTowardsTarget() { var direction = (target.position - transform.position).normalized; direction.y = 0; characterController.Move(direction * (moveSpeed * Time.deltaTime)); } private void MoveAway() { var direction = (transform.position - target.position).normalized; direction.y = 0; characterController.Move(direction * (moveSpeed * Time.deltaTime)); } private void Attack() { if (Time.time - lastAttackTime < attackCooldown) return; if (weapon == null) return; if (!HasLineOfSight()) return; lastAttackTime = Time.time; weapon.Shoot(); } private bool HasLineOfSight() { if (target == null) return false; var direction = (target.position - firePoint.position).normalized; var distance = Vector3.Distance(firePoint.position, target.position); if (Physics.Raycast(firePoint.position, direction, out var hit, distance, obstacleMask)) { return hit.collider.transform == target; } return true; } private void HandleDeath() { enabled = false; Destroy(gameObject, 2f); } public void TakeDamage(float damage) { healthSystem?.TakeDamage(damage); } public Transform GetTransform() => transform; } }