EnemyAi
Thu Apr 28 2022 14:10:26 GMT+0000 (Coordinated Universal Time)
Saved by @DanDHenshaw
using UnityEngine; using UnityEngine.AI; using Random = UnityEngine.Random; public class EnemyAi : MonoBehaviour { public NavMeshAgent agent; public Transform player; private AudioSource audioSource; private Animator animator; public LayerMask whatIsGround, whatIsPlayer; public float health = 100f; [Header("Patrolling")] public Vector3 walkPoint; private bool walkPointSet; public float walkPointRange; [SerializeField] private AudioClip[] footstepSounds; [Header("Attacking")] public float timeBetweenAttacks, reloadTime; private bool alreadyAttacked; public GameObject projectile; public float damage; [Header("States")] public float sightRange; public float attackRange; public bool playerInSightRange, playerInAttackRange; public GameObject[] guns; public AudioClip[] shootingSounds; public AudioClip[] reloadingSounds; public AudioClip reloadClip, shotClip; public ParticleSystem muzzleFlash; public Animator gunAnimator; public AudioSource gunAudioSource; public Transform spawnPoint; public float currentAmmo; public float ammo; private Vector3 lastPosition; private float moveMinimum = 0.01f; private void Awake() { player = GameObject.Find("PlayerController").transform; agent = GetComponent<NavMeshAgent>(); audioSource = GetComponent<AudioSource>(); animator = GetComponent<Animator>(); int randomGun = Random.Range(0, guns.Length); guns[randomGun].SetActive(true); gunAnimator = guns[randomGun].GetComponent<Animator>(); gunAudioSource = guns[randomGun].GetComponent<AudioSource>(); muzzleFlash = guns[randomGun].GetComponentInChildren<ParticleSystem>(); spawnPoint = guns[randomGun].transform.Find("AttackPoint"); reloadClip = reloadingSounds[randomGun]; shotClip = shootingSounds[randomGun]; if (randomGun == 0) { ammo = 6; damage = 10; } else if (randomGun == 1) { ammo = 2; damage = 20; } currentAmmo = ammo; } private void Start() { GameManager.instance.enemies++; GameManager.instance.enemiesSpawned = true; } private void Update() { // Check for player in sight and attack range playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer); playerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer); if(!playerInSightRange && !playerInAttackRange) Patroling(); if(playerInSightRange && !playerInAttackRange) ChasePlayer(); if(playerInSightRange && playerInAttackRange) AttackPlayer(); if (IsMoving()) { animator.SetBool("Walking", true); } else { animator.SetBool("Walking", false); } lastPosition = transform.position; } private void Patroling() { if (!walkPointSet) SearchWalkPoint(); if (walkPointSet) agent.SetDestination(walkPoint); Vector3 distanceToWalkPoint = transform.position - walkPoint; // Reached walkpoint if (distanceToWalkPoint.magnitude < 1f) walkPointSet = false; } private void SearchWalkPoint() { // Calculate random point in range float randomX = Random.Range(-walkPointRange, walkPointRange); float randomZ = Random.Range(-walkPointRange, walkPointRange); walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ); if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround)) walkPointSet = true; } private void ChasePlayer() { agent.SetDestination(player.position); } private void AttackPlayer() { // Make sure enemy doesn't move agent.SetDestination(transform.position); transform.LookAt(player); if (!alreadyAttacked && currentAmmo > 0) { // Attack GameObject _projectile = Instantiate(projectile, spawnPoint.position, Quaternion.identity); _projectile.GetComponent<ProjectileScript>().damage = damage; Rigidbody rb = _projectile.GetComponent<Rigidbody>(); rb.AddForce(transform.forward * 32f, ForceMode.Impulse); rb.AddForce(transform.up * 0f, ForceMode.Impulse); muzzleFlash.Play(); gunAnimator.SetTrigger("Shot"); gunAudioSource.clip = shotClip; gunAudioSource.Play(); currentAmmo--; alreadyAttacked = true; Invoke(nameof(ResetAttack), timeBetweenAttacks); } else if (currentAmmo <= 0 && !alreadyAttacked) { currentAmmo = ammo; gunAnimator.SetTrigger("Reload"); gunAudioSource.clip = reloadClip; gunAudioSource.Play(); alreadyAttacked = true; Invoke(nameof(ResetReload), reloadTime); } } private void ResetAttack() { alreadyAttacked = false; } private void ResetReload() { alreadyAttacked = false; } public void Footstep() { audioSource.clip = footstepSounds[Random.Range(0, footstepSounds.Length)]; audioSource.Play(); } public void TakeDamage(float damage) { health -= damage; if (health <= 0) { Invoke(nameof(DestroyEnemy), 0f); } } private void DestroyEnemy() { GameManager.instance.enemiesDead++; Destroy(gameObject); } bool IsMoving() { float distance = Vector3.Distance(transform.position, lastPosition); return (distance > moveMinimum); } private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, attackRange); Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, sightRange); } }
Comments