using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine; using Utility; public class Zombie : MonoBehaviour { [SerializeField] List Noises; [SerializeField] private float _speed = 0.5f; [SerializeField] private float _rotateSpeed = 180.0f; [SerializeField] private float _attackRange = 1.3f; [SerializeField] private float _idleThresholdFactor = 0.2f; [SerializeField] private float _noiseDelay = 5.0f; [SerializeField, ShowOnly] private float _noiseTimer; private Rigidbody _rb; private AudioSource _audioSource; private bool _fadeOutNoise = false; private Animator _animator; private bool _isAttacking = false; private float _idleThreshold; private Quaternion _initialRotation; [ContextMenu("Kill Zombie")] private void TestDIe() { Die(); } void Start() { _rb = GetComponent(); _noiseTimer = Random.Range(0.3f * _noiseDelay, 1.5f * _noiseDelay); _audioSource = GetComponent(); _animator = GetComponent(); _idleThreshold = _speed / _idleThresholdFactor; _initialRotation = transform.rotation; } void Update() { //_idleThreshold = _speed / _idleThresholdFactor; UpdateNoise(); if (!_isAttacking) { MoveTowardsPlayer(); } } private void MoveTowardsPlayer() { Vector3 direction = (GameManager.Instance.Player.transform.position - transform.position); Quaternion goalRotation = Quaternion.LookRotation(direction); transform.rotation = Quaternion.RotateTowards(transform.rotation, goalRotation, _rotateSpeed * Time.deltaTime); float diff = direction.magnitude; if (diff <= _attackRange && !_isAttacking) { _animator.SetFloat("Running", 0); _animator.SetBool("Idle", false); StartCoroutine(Attack()); } else { Vector3 oldPosition = _rb.position; _rb.MovePosition(_rb.position + direction * _speed * Time.deltaTime); float dist = Vector3.Distance(oldPosition, _rb.position); if (dist > _idleThreshold * Time.deltaTime) { _animator.SetBool("Idle", false); _animator.SetFloat("Running", 1); } else { _animator.SetFloat("Running", 0); _animator.SetBool("Idle", true); } } } private IEnumerator Attack() { _isAttacking = true; _animator.SetBool("Attack", true); yield return new WaitForSeconds(1.5f); _animator.SetBool("Attack", false); // check if actually hit Vector3 direction = (GameManager.Instance.Player.transform.position - transform.position); float diff = direction.magnitude; if (diff <= _attackRange + 0.5f) { GameManager.Instance.Player.GetComponent().PickupItem(null); } _isAttacking = false; } private void UpdateNoise() { if (!_fadeOutNoise) { _noiseTimer -= Time.deltaTime; if (_noiseTimer < 0) { _noiseTimer = _noiseDelay; PlayRandomNoise(); } } else { _audioSource.volume -= _audioSource.volume * Time.deltaTime; } } private void PlayRandomNoise() { if (!_audioSource.isPlaying) { _audioSource.clip = Noises[Random.Range(0, Noises.Count)]; _audioSource.Play(); } } private void Die() { GameObject particleEffect = Instantiate(GameManager.Instance.ZombieDeathByDisableParticleEffect, transform.position, Quaternion.Euler(-90, 0, 0), GameManager.Instance.transform); AudioSource audio = particleEffect.GetComponent(); audio.clip = GetComponentInParent().ZombieDeathByDisableSoundeffects[Random.Range(0, GetComponentInParent().ZombieDeathByDisableSoundeffects.Count)]; audio.Play(); Destroy(gameObject); } public void FadeOutNoise() { _fadeOutNoise = true; } }