본문 바로가기
게임 프로그래밍/게임개발 중급

게임개발 중급(58) - Monster Killer(20)

by jyppro 2023. 6. 21.

Monster Killer(20)

이전엔 NavMesh를 사용하는 방법에 대해서 알아보았습니다. 이제는 스크립트를 통해서 해당 오브젝트의 움직임을 정의해야 합니다.

 

스크립트 생성

이제 몬스터가 움직일 수 있는 지형정보는 완성이 되었으니 움직이도록 만들어주는 코드를 작성해야 합니다. 스크립트에서도 마찬가지로 NavMesh를 사용합니다.

 

MonsterMovement

using System.Collections;
using UnityEngine;
using UnityEngine.AI;

public class MonsterMovement : MonoBehaviour
{
    private NavMeshAgent navMeshAgent;
    private bool isMoving = false;

    [SerializeField] private float minMoveDelay = 1f; // 최소 이동 딜레이
    [SerializeField] private float maxMoveDelay = 3f; // 최대 이동 딜레이

    private void Awake()
    {
        navMeshAgent = GetComponent<NavMeshAgent>();
    }

    private void Start()
    {
        // 처음에 이동을 시작하도록 호출
        StartCoroutine(MoveCoroutine());
    }

    private IEnumerator MoveCoroutine()
    {
        while (true)
        {
            if (!isMoving)
            {
                // 이동을 시작하기 전에 랜덤한 딜레이를 줍니다.
                float moveDelay = Random.Range(minMoveDelay, maxMoveDelay);
                yield return new WaitForSeconds(moveDelay);

                // 새로운 목표 지점을 선택하여 이동합니다.
                Vector3 targetPosition = GetRandomTargetPosition();
                MoveTo(targetPosition);
            }
            yield return null;
        }
    }

    private void MoveTo(Vector3 targetPosition)
    {
        isMoving = true;
        navMeshAgent.SetDestination(targetPosition);
    }

    private Vector3 GetRandomTargetPosition()
    {
        // 랜덤한 위치를 선택하여 반환합니다.
        Vector3 randomPosition = new Vector3(Random.Range(-10f, 10f), 0f, Random.Range(-10f, 10f));
        return randomPosition;
    }

    private void Update()
    {
        if (isMoving && navMeshAgent.remainingDistance <= navMeshAgent.stoppingDistance)
        {
            // 이동이 완료되었을 때 이동 상태를 해제합니다.
            isMoving = false;
        }
    }
}

스크립트를 사용하기 위해 using문에서 AI와 Collection을 추가해 주어야 합니다. NavMeshAgent를 통해서 몬스터의 움직임을 정의해 주어야 합니다. GetRandomTargetPosition을 통해 -10~10사이의 랜덤한 좌표값을 받아와 코루틴을 통해 움직임이 없으면 랜덤 딜레이를 준 뒤에 목표지점을 설정하여 움직이도록 만들고 이동이 끝나면 상태변수 isMoving을 해제하여 이동이 완료되도록 판단해 줍니다.

 

NavMesh의 원래 사용목적은 주어진 목적지를 향해 움직이도록 마치 네비게이션과 같은 역할을 정의해주는 것입니다. 하지만 코드를 이렇게 작성한다면, 목적지에 대한 정보를 계속해서 수정하기 때문에 랜덤하고 목적지 없이 자유롭게 움직이는 것처럼 만들 수 있습니다. 그럼 이제 게임을 한번 실행해 보겠습니다.

 

게임 실행

몬스터-움직임
몬스터 움직임

게임을 실행하면, 몬스터가 Scream을 짧게 실행한 뒤에 랜덤하게 움직입니다. 현재 방향을 틀어 뒤를 바라보고 있습니다.

이제 해당 동작을 모든 몬스터들이 할 수 있도록 전부 넣어주어야 합니다.

 

<NEXT>

오늘은 NavMesh를 사용하여 랜덤하게 움직이는 스크립트를 작성해 보았습니다. 다음에는 몬스터 움직임에 맞춰 따라가는 카메라에 대해서 다뤄보겠습니다. 감사합니다.