배틀레드_길찾기와 월드맵

양규빈·2023년 12월 30일

유니티

목록 보기
10/34
post-thumbnail

길찾기

RPG게임에는 길찾기 기능을 사용해야할 때가 있습니다.
특정 재료를 찾아야하거나, 특정 던전을 찾아야 할때나.
그런 경우가 해당될 것입니다.

게임 개발에서 이러한 길찾기 기능은
주로 A스타 알고리즘을 활용하여 구현하곤 합니다.
A스타 알고리즘이란, 출발지와 도착지가 정해져있을 때, 경로 이동 간 최상의 경로를 추정하는 순위값인 휴리스틱 추정 값을 계산하여 최소비용을 따라서 방문하는 알고리즘입니다.

유니티의 navMesh 시스템 또한 이러한 에이스타 알고리즘을 이용한 것으로 알려져 있습니다.

길찾기 구현

인게임 상에서 길찾기를 구현한 영상 링크입니다.

길찾기 안내의 구현은 플레이어 캐릭터에 부착된 navMeshAgent 컴포넌트를 활용했습니다.



코드

길안내 기능을 구현한 스크립트인 PathFinder는 플레이어 캐릭터에 부착된 컴포넌트입니다.

FindPathStart 함수에서 매개변수로 받은 벡터3 좌표값을 타겟으로, Destination을 세팅하고 경로를 받아서 Draw하는 방식으로 구현했습니다.

즉, 네브메쉬 상에서 지원하지 않는 경로라면 길안내는 이뤄지지 않습니다.

이러한 길찾기 기능은 인게임 컨텐츠의 요구에 따라서 적절하게 호출되어 필요한 좌표값을 변수로 보내어, 길안내를 하도록 합니다.

상단의 영상에서 보여주는 합성 아이템 재료 찾기, 합성대 찾기 등이 이에 해당됩니다.

이때.

상단의 스크롤뷰 객체를 관리하는 GetResourcePrintUI클래스는 아이템 클래스를 매개변수로 받아서, 태그에 따라 아이템 타입을 분류하고, 각 아이템에 해당하는 좌표를 매칭하여 FindPathStart()함수를 호출합니다.

아이템 클래스 변수를 받은 Scroll_Start 함수가 아이템 이름과 이미지 등을 UI에 출력합니다.
그리고, 아이템 획득처를 출력하는 GetItemWithAttributes 함수를 호출합니다.

해당 함수는
각 아이템을 얻을 수 있는 방법을 출력합니다.
UI를 통해서 아이템 획득처를 출력하고, 버튼 함수를 연결하여 버튼 클릭 시 해당 좌표를 안내받을 수 있도록 합니다.

획득처 안내 함수는 위와 같습니다.



월드맵

월드맵은
미니맵을 크게 키워서, 플레이어가 전체 맵을 한눈에 볼 수 있도록 합니다.

이때, 월드맵을 클릭하면 클릭한 지점과 실제 월드 상의 좌표를 매칭하여 길안내를 할 수도 있습니다.

월드맵 구현 영상

상단의 링크는 월드맵을 구현한 상세 영상입니다.

드래그하여 월드맵을 이동하는 것이 가능하고, 짧게 터치하여 월드맵을 찍은 지점의 좌표를 가져와 PathFind합니다.

이러한 미니맵은 미니맵 카메라를 적절히 제어하는 것으로 구현했습니다.



구현

미니맵을 클릭하였을 때 호출되는 함수와
종료 버튼을 클릭했을 때 호출되는 함수입니다.

월드맵은 카메라 제어와 밀접한 관련이 있기 때문에 옵저버 패턴으로 함수의 시작과 끝을 알려줍닙다.

카메라를 enum으로 분류하여, State를 나눕니다.
월드맵 상태에서는 캐릭을 추적하여 따라다니지 않도록 합니다.

그리고 월드맵 상태에서는 미니맵이 촬영하는 Size를 35로 넓혀서, 많은 범위를 보여줄 수 있도록 합니다.


월드맵 제어 함수에서는 짧은 터치와 드래그를 분류하여 입력받습니다.
짧은 터치는 클릭한 위치를 좌표로 변환하여 PathFind 합니다.

터치하여 입력받은 clickPosition 값은 x값의 경우 0~1920 / y는 0~1080이 설정됩니다.

그리고 미니맵은 35 사이즈로 촬영되고 있기 때문에, 중앙값을 기준으로 -35 ~ 35. 즉. 70의 값이 맵의 축을 나타내는 범위가 됩니다.

그렇기에 1920과 1080(정확히는 스크린의 크기 값)에 촬영값(여기서는 35*2)_offsetX,와 offsetY를 나누어 값을 보정합니다.

좀더 쉽게 설명하자면,
게임 화면을 기준으로 miniMap의 촬영 사이즈값 x2(여기서는 70) 만큼 스크린의 x축, y축을 나눕니다.

이렇게 되면 스크린의 터치값을 실제 오픈 월드의 x값, z값으로 보정할 수 있게됩니다.
단, 보정에 앞서. 좌표의 시작지점은, 카메라의 최하단 좌측점으로 고정해두어야 합니다.

스크린의 값은 음수가 없고, 오로지 양수로 늘어나기 때문입니다.
상단의 그림에서는 사각형의 좌측하단 꼭짓점이 됩니다.

        init_worldPos -= new Vector3(cameraFarSize, 0, cameraFarSize);

최조 좌표값 고정은 위 로직으로 구할 수 있습니다.

드래그를 감지한 이후에는 드래그한 이동량을 인풋하여 속도값을 곱하여(소수를 곱하여 이동량을 낮춥니다) 미니맵 카메라를 translate합니다.

이때, 미니맵 카메라가 일정 범위 이상 넘어가지 못하도록.
월드상에 존재하는 벽(콜라이더)을 레이로 쏴서 탐지, 일정 범위 내에 벽이 있을 경우 false값을 얻어, 이동하지 않도록 합니다.

profile
훌륭한 개발자를 꿈꾸는 중입니다

0개의 댓글