using UnityEngine; [RequireComponent(typeof(Animator))] [RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(AudioSource))] public class ZombieController : MonoBehaviour { private static readonly int DieHash = Animator.StringToHash("Die"); private static readonly int IsAttackingHash = Animator.StringToHash("isAttacking"); private static readonly int IsWalkingHash = Animator.StringToHash("isWalking"); private static readonly int IsRunningHash = Animator.StringToHash("isRunning"); [Header("Health")] private readonly float maxHealth = 50; private float currentHealth; [Header("Movement")] private readonly float walkSpeed = 1f; private readonly float runSpeed = 2f; private readonly float runDistance = 5f; // od kedy začne bežať private readonly float attackDistance = 1.5f; // od kedy útočí [Header("Attack")] private readonly float attackDamage = 10f; private readonly float attackCooldown = 1f; private float lastAttackTime; [Header("Sounds")] [SerializeField] private AudioClip[] sfx; [SerializeField] private int sfxDelay = 5; // seconds private Transform player; private Animator animator; private AudioSource audioSource; private float lastSfxPlay; private bool IsDead() => currentHealth == 0; private void Start() { currentHealth = maxHealth; animator = GetComponent(); player = GameObject.FindGameObjectWithTag("Player").transform; audioSource = GetComponent(); } private void Update() { if (IsDead()) return; PlaySfx(); float distance = Vector3.Distance(transform.position, player.position); if (distance <= attackDistance) { StopMoving(); TryAttack(); } else if (distance <= runDistance) { MoveToPlayer(runSpeed); animator.SetBool(IsRunningHash, true); animator.SetBool(IsWalkingHash, false); animator.SetBool(IsAttackingHash, false); } else { MoveToPlayer(walkSpeed); animator.SetBool(IsWalkingHash, true); animator.SetBool(IsRunningHash, false); animator.SetBool(IsAttackingHash, false); } } private AudioClip PickSfx() { return sfx[UnityEngine.Random.Range(0, sfx.Length)]; } private void PlaySfx() { if (Time.time - lastSfxPlay <= sfxDelay) { return; } var clip = PickSfx(); audioSource.PlayOneShot(clip); lastSfxPlay = Time.time; } private void MoveToPlayer(float speed) { Vector3 direction = (player.position - transform.position).normalized; transform.position += speed * Time.deltaTime * direction; transform.LookAt(new Vector3(player.position.x, transform.position.y, player.position.z)); } private void StopMoving() { animator.SetBool(IsWalkingHash, false); animator.SetBool(IsRunningHash, false); } private void TryAttack() { animator.SetBool(IsAttackingHash, true); if (Time.time - lastAttackTime >= attackCooldown) { lastAttackTime = Time.time; Debug.Log($"{gameObject.name} attacked player by {attackDamage} damage"); // player.GetComponent()?.TakeDamage(attackDamage); } } public void TakeDamage(float amount) { if (IsDead()) return; currentHealth -= amount; Debug.Log($"{gameObject.name} took {amount} damage. HP: {currentHealth}/{maxHealth}"); if (currentHealth <= 0) Die(); } private void Die() { Debug.Log($"{gameObject.name} is dead"); animator.SetTrigger(DieHash); Destroy(gameObject, 2f); } }