[TIL] Unity - 몬스터 AI (1)

MINO·2024년 6월 28일
0
post-thumbnail

2024-06-28


몬스터의 4가지 상태

구현하고자 하는 몬스터는 4가지 상태를 갖는다.

  1. Idle (Patrol) : 몬스터가 생성됐을 때의 상태이다.
    • 주변을 배회하며 느린 속도로 이동한다.
  2. Chase : 몬스터가 타겟을 감지했을 때의 상태이다.
    • 타겟을 향해 빠른 속도로 이동한다.
  3. Attack : 몬스터의 사정 거리 안에 타겟이 존재하여 공격하는 상태이다.
    • 몬스터가 타겟을 일정 시간마다 공격한다.
  4. Death : 몬스터의 HP 가 0 이 되어 소멸하는 상태이다.
    • 몬스터가 보상을 드랍하고, 소멸한다.

FSM 와이어 프레임


Idle

일정 범위 내로 무작위 목적지를 설정해 주변을 배회한다.

IEnumerator Idle()
{
	Debug.Log("Idle State");

	// 랜덤한 목적지 설정
	Vector3 newDestination = GetRandomNavMeshPosition();
	
	// 목적지 설정
    agent.speed = idleSpeed;
	agent.SetDestination(newDestination);

	// Idle 상태 지속 시간 대기
	yield return new WaitForSeconds(idleTime);
}

private Vector3 GetRandomNavMeshPosition()
{
	Vector3 randomDirection = Random.insideUnitSphere * wanderRadius;

	randomDirection += transform.position;

	NavMeshHit hit;
	NavMesh.SamplePosition(randomDirection, out hit, wanderRadius, NavMesh.AllAreas);

	return hit.position;
}

결과

수정 필요 : 이동 방향으로 회전하기

agent.updateRotation = true; 로는 제대로 회전하지 않는 상태


Idle <-> Chase

주변을 배회하는 몬스터의 Trigger 에 타겟 (플레이어, NPC)가 감지되었을 때 변경


private void OnTriggerEnter2D(Collider2D other)
{
	if (other.CompareTag("Player")) 
		return;
        
	target = other.transform;
        
	ChangeState(State.Chase);
}

private void OnTriggerExit2D(Collider2D other)
{
	if (other.CompareTag("Player"))
		return;

	target = null;

	ChangeState(State.Idle);
}

Chase

타겟을 향해 움직인다.

IEnumerator Chase()
{
	Debug.Log("Chase State");
	
    // 목표까지의 남은 거리가 멈추는 지점보다 작거나 같으면
	if (agent.remainingDistance <= agent.stoppingDistance)
	{
		// StateMachine 을 Attack 으로 변경
		ChangeState(State.Attack);
		yield return null;
	}
       
	else
	{
		agent.speed = chaseSpeed;
		agent.SetDestination(target.position);
		yield return null;
	}
}

결과

수정 필요 : 이동 방향으로 회전하기, 몬스터마다 탐지 범위 다르게 설정하기


TIL 마무리

이어서 Attack 상태와 Death 상태를 추가해야 한다.

처음에는 강의에서 배운 BaseState 를 상속 받은 각각의 State 들을 사용하려고 했지만,
NavMesh 와 함께 사용하려고 하니 잘 되지 않아
코루틴을 사용하는 방식으로 수정하였다.

일단은 코루틴을 사용하는 방식으로 몬스터 AI 가 잘 동작하는지 확인해보고,
추후 리팩토링을 통해 다른 FSM 방식으로 수정해봐야겠다.

profile
안녕하세요 게임 개발하는 MINO 입니다.

0개의 댓글