본문 바로가기

유니티

유니티 강좌 04. 2D 랜덤 패트롤 AI

게임에서 적을 만났는데 적이 동상처럼 가만히 서있기만 한다면 어떨까요? 분명 엄청 지루한 게임이 될 것입니다. 또는 적이 어디에 있는지 뻔히 알기 때문에 스테이지를 깨기 매우 쉬워지겠죠. 잘 만들어진 게임을 보면 적들은 플레이어가 근처에 있지 않더라도 항상 바쁘게 움직이고 있습니다. 꼭 적이 아니라 주민 npc, 동물, 등 게임에 등장하는 캐릭터들이 항상 움직이고 있는 모습을 볼 수 있죠. 이번 강좌에서는 2D 랜덤 패트롤을 구현해 보도록 하겠습니다.


 

유니티 강좌 02. 2D 플레이어 이동

지난 강좌에서 유니티의 기본 인터페이스에 대해서 배웠습니다. 그럼 이제 본격적으로 유니티를 사용해 봐야겠죠. 게임에서 가장 기본적인 요소 중 하나가 바로 플레이어입니다. 그중에서도 제

torotoblog.tistory.com

 

유니티 강좌 03. 2D 플레이어 추적 AI 만들기

모든 게임에 적이 있지는 않지만, 대부분의 게임에는 플레이어가 무찌를 수 있는 적이 등장합니다. 하지만 적들은 사람이 직접 조종하는 캐릭터가 아니다 보니 스스로 판단하고 움직이는 AI가

torotoblog.tistory.com


우선 패트롤을 적용시킬 오브젝트를 만들어봅시다. 저번 강좌에서 사용했었던 MoveTowards() 함수를 사용할 것이기 때문에 따로 컴포넌트들은 필요가 없고, Patrol 스크립트를 만들어서 이것만 적용시켜 주도록 하겠습니다.

using UnityEngine;

public class Patrol : MonoBehaviour
{
    public float speed;
    public float startWaitTime;
    private float waitTime;

    public Transform moveSpot;
    public float minX;
    public float maxX;
    public float minY;
    public float maxY;
    
    private void Start()
    {
        waitTime = startWaitTime;
        moveSpot.position = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
    }

    private void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position, moveSpot.position, speed * Time.deltaTime);

        if (Vector2.Distance(transform.position, moveSpot.position) < 0.2)
        {
            if (waitTime <= 0)
            {
                moveSpot.position = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
                waitTime = startWaitTime;
            }
            else
            {
                waitTime -= Time.deltaTime;
            }
        }
    }
}

전체 코드는 이렇습니다. 하나씩 살펴보도록 하죠.

public float speed;
public float startWaitTime;
private float waitTime;
public Transform moveSpot;
public float minX;
public float maxX;
public float minY;
public float maxY;

이번에 사용될 변수는 총 7개가 있습니다. 오브젝트의 이동 속도인 speed, 목적지에 도달하면 사용하게 될 타이머 waitTime과 startWaitTime, 오브젝트가 패트롤 할 구역을 설정하는 moveSpot과 minX, maxX, minY, maxY가 있습니다.

private void Start()
{
    waitTime = startWaitTime;
    moveSpot.position = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
}

Start() 함수에서는 두 가지 변수들을 초기화 시켜줄 겁니다. 우선 첫 줄을 보면 타이머를 초기화 시키는 것을 볼 수 있는데요, startWaitTime은 오브젝트가 멈춰 있을 시간의 고정 값이고, waitTime은 실제로 시간을 잴 때 사용되는 변수입니다. 나중에 Update() 함수에서 조금 더 살펴 보도록 하겠습니다.

두 번째로는 moveSpot.position을 초기화 하는데요, 오브젝트가 이동할 위치를 랜덤 한 좌표로 설정하는 겁니다. Random.Range() 함수를 사용해서 min, max 값 사이에 있는 랜덤 한 숫자를 하나씩 정해서 랜덤 좌표를 생성하는 거죠.

private void Update()
{
    transform.position = Vector2.MoveTowards(transform.position, moveSpot.position, speed * Time.deltaTime);

    if (Vector2.Distance(transform.position, moveSpot.position) < 0.2)
    {
        if (waitTime <= 0)
        {
            moveSpot.position = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
            waitTime = startWaitTime;
        }
        else
        {
            waitTime -= Time.deltaTime;
        }
    }
}

Update() 함수는 크게 두 동작으로 나눠져 있습니다. 우선 첫 줄을 보면 저번 강좌에서 사용했던 MoveTowards() 함수를 통해 오브젝트를 moveSpot의 위치로 이동시킵니다. 시작할 때 moveSpot의 위치를 랜덤하게 바꿨기 때문에 Update() 함수 내에서는 이동만 시키면 됩니다. 

두 번째로는 타이머입니다. 만약에 오브젝트가 moveSpot에 도달하면 타이머가 작동하기 시작합니다. 여기서 거리가 0.2보다 적을 때로 설정한 이유는 컴퓨터 사양에 따라 거리가 정확하게 0이 되지 않을 수도 있을 수 있기 때문입니다. 타이머는 waitTime 값이 0보다 같거나 작은지 확인하는 것으로 시작합니다. 만약 waitTime이 0보다 같거나 작으면 다음으로 이동할 좌표를 새로 설정하고, 이어서 타이머를 재설정합니다. startWaitTime이 고정 값이기 때문에 이 값으로 설정하면 되겠죠? 만약 아직 0보다 크다면 Time.deltaTime을 빼줌으로써 카운트다운을 하게 됩니다. 생각보다 간단한 원리죠?

사진으로 한 번 더 살펴봅시다. 우리가 설정한 min, max 값들은 위 좌표처럼 설정돼있는 좌표 내에서 랜덤하게 선택되게 됩니다. 오브젝트가 움직일 수 있는 범위를 설정해 주는 것이라고 생각하면 되겠습니다.

다시 유니티로 돌아와서 오브젝트 Inspector 창을 보면 변수들이 추가되어 있습니다. 원하는 값들로 채워줍시다. 저는 속도 5, 대기 시간 2, 각 min max 값들에는 -20과 20을 넣어줬습니다. Move Spot의 경우 새로운 빈 오브젝트를 하나 만들어서 적용시켜주시면 됩니다.

변수 설정이 끝났다면 한번 실행시켜 봅시다. 유니티 중앙 상단에 있는 플레이 버튼을 클릭하면 게임이 실행되고 오브젝트가 랜덤하게 잘 움직입니다. 위치에 도달했다면 2초 대기 후 새로운 위치로 다시 움직이네요. 성공입니다.


 

유니티 강좌 05. 화면 흔들림 효과

게임 속에는 다양한 효과들이 적용되어 있습니다. 일반적으로는 알지 못하는 효과이더라도 모두 게임을 역동적으로 만들어주는 중요한 역할을 하고 있죠. 그 중 하나가 바로 화면 흔들림 효과

torotoblog.tistory.com