using System.Collections;
using UnityEngine;
using UnityEngine.AI;
public class Stage4Enemy : EnemyBase
{
public float detectionRadius = 5.0f;
public LayerMask playerLayer;
private GameObject detectedPlayer = null;
public NavMeshAgent navAgent;
public float attackRange = 5.0f; // 공격 범위
protected override void Start()
{
base.Start();
navAgent = GetComponent<NavMeshAgent>();
}
protected override void Update()
{
base.Update();
PlayerDetect();
RotateTowardsPlayer();
}
protected override IEnumerator EnemyAnimation()
{
while (true)
{
switch (enemyState)
{
case EnemyState.Idle:
animator.SetInteger("state", 0);
break;
case EnemyState.Walk:
animator.SetInteger("state", 1);
break;
case EnemyState.GetHit:
animator.SetInteger("state", 2);
yield return new WaitUntil(() => animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f && animator.GetCurrentAnimatorStateInfo(0).IsName("GetHit"));
enemyState = EnemyState.Idle;
navAgent.isStopped = false; // 다시 적을 활성화
break;
case EnemyState.Die:
animator.SetInteger("state", 3);
targetPoint.SetActive(false);
this.GetComponent<Collider>().enabled = false;
yield return new WaitUntil(() => animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f && animator.GetCurrentAnimatorStateInfo(0).IsName("Die"));
Destroy(this.gameObject);
break;
case EnemyState.Attack:
if (detectedPlayer != null && Vector3.Distance(transform.position, detectedPlayer.transform.position) <= attackRange)
{
animator.SetInteger("state", 4);
yield return new WaitUntil(() => animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f && animator.GetCurrentAnimatorStateInfo(0).IsName("Attack"));
}
else
{
enemyState = EnemyState.Idle;
}
break;
}
yield return null;
}
}
void RotateTowardsPlayer()
{
if (detectedPlayer != null)
{
Vector3 lookDirection = (detectedPlayer.transform.position - transform.position).normalized;
lookDirection.y = 0;
Quaternion lookRotation = Quaternion.LookRotation(lookDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5.0f);
}
}
void PlayerDetect()
{
// Player의 체력이 0 이하인 경우
if (GameManager.Instance.PlayerHP <= 0)
{
detectedPlayer = null;
enemyState = EnemyState.Idle;
navAgent.isStopped = true;
return; // Idle 상태를 유지하고 함수 종료
}
// 다른 상황 처리
if (enemyHP <= 0 || enemyState == EnemyState.GetHit) return;
Collider[] detectedPlayers = Physics.OverlapSphere(transform.position, detectionRadius, playerLayer);
if (detectedPlayers.Length > 0)
{
navAgent.isStopped = false;
detectedPlayer = detectedPlayers[0].gameObject;
float distanceToPlayer = Vector3.Distance(transform.position, detectedPlayer.transform.position);
if (distanceToPlayer > attackRange)
{
enemyState = EnemyState.Walk;
navAgent.SetDestination(detectedPlayer.transform.position);
}
else if (distanceToPlayer <= attackRange)
{
navAgent.isStopped = true;
RotateTowardsPlayer();
enemyState = EnemyState.Attack;
}
}
else
{
detectedPlayer = null;
enemyState = EnemyState.Idle;
}
}
protected override void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Bullet"))
{
enemyHP--;
Destroy(other.gameObject);
if (enemyHP <= 0)
{
enemyState = EnemyState.Die;
navAgent.isStopped = true;
}
else
{
if (enemyState != EnemyState.GetHit)
{
navAgent.isStopped = true; // 적을 중지
enemyState = EnemyState.GetHit;
animator.Play("GetHit", -1, 0f);
}
}
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(this.transform.position, detectionRadius);
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(this.transform.position, attackRange);
}
}
반응형
'KDT > 3D 콘텐츠 제작' 카테고리의 다른 글
[HeroShooter] 벽(콜라이더)에 부딫히면 떨리는 문제 해결 (0) | 2023.08.29 |
---|---|
[HeroShooter] 스테이지2~3: 움직이지 않고 원거리 공격을 하는 몬스터 구현 (1) | 2023.08.27 |
[HeroShooter] Stage2. Enemy의 피격과 사망, 인식 구현 (0) | 2023.08.24 |
[HeroShooter] Ray와 Overlap을 이용한 적 감지 구현 (0) | 2023.08.23 |
[HeroShooter] Tutorial UI 및 트리거 구현 (0) | 2023.08.22 |