들어가기에 앞서, 기획팀에서 요구한 미니맵의 기능은 다음과 같습니다.
1. 플레이어가 아직 탐색하지 않은 방은 안개로 표현하여, 알 수 없게 한다.
2. 플레이어가 지나친 방이나 인접한 방을 표시한다.
3. 미니맵은 전체적인 방들의 구조와 동일하게 한다.
4. 추후 미니맵과 관련된 아이템이 추가되는 것을 고려한다.
다음, 미니맵과 관련하여 랜덤맵에 대해서 분석해보겠습니다.
현재 랜덤맵 제너레이터가 생성하는 맵은
이중배열의 형태로 만들어집니다.
랜덤으로 배열의 길이를 구하고, 이중 배열의 중앙을 시작위치로 하여, 랜덤한 방향으로 가지를 뻗어나가 방을 생성하는 방식이죠.
때문에, 미니맵의 구현 역시
이중배열을 이용한 grid 방식으로 구현하도록 했습니다.

일반적인 미니맵의 구현은, rawImage를 응용하여, 카메라가 고각에서 아래로 내리쬐는 상을 투영하는 방식으로 이뤄집니다.
하지만, 이번에 구현하는 미니맵 출력 방식은 UI 캔버스에 그리드 컴포넌트를 이용해서, 렌더하는 방식으로 결정했습니다.
이것이, 기획팀의 구현의도에 부합한 출력 방식이었습니다.

그리드 레이아웃 그룹에 이중배열의 각 원소를 나타내는 UI컴포넌트를 붙입니다.

FixedColumnCount의 ConstraintCount 값을 수정하여, 이중배열의 행에 해당하는 크기만큼 고정합니다.
이렇게 하면, 이중배열을 그리드 형태로 출력하는 것이 가능합니다.
이때, 맵에 생성된 방이 너무 많을 경우에, 백그라운드 이미지를 벗어나는 경우가 발생할 수 있으니. Rctk Mask 2D로 고정해줍니다.

랜덤맵 제너레이터에서 제공하는 데이터는 이중 배열의 형태로 제공되는 Room들의 집합입니다.
다만, 해당 데이터를 곧바로 미니맵의 형태로 가공하여 사용할 수는 없었습니다.
문제점
랜덤맵 제너레이터 문서에서 확인할 수 있다시피,
roomPoses 이중배열은, 1개 반복의 방 생성 갯수인 length의 2배로 설정되어있습니다.
이는, 정중앙에 시작방을 두고 가지를 뻗어나갈 때.
특정 방향으로만 쭉 뻗어나갈 때를 고려하여 설정한 범위였습니다.
그렇기 때문에 해당 크기의 이중배열을 그대로 사용한다면, 불필요한 패딩 공간을 많이 사용하게 됩니다.

roomBoard는 모든 방을 표현할 수 있는 최소한의 이중배열입니다.
기획팀에서 기획한 미니맵에서,
맵에 저장될 State는 단순하게 보자면 세 가지 입니다.
여기서, 지나치거나 인접한 방은 Gray 컬러로 칠하고,
그렇지 않은 방은 Black(안개),
플레이어가 위치한 방은 White 컬러로 칠할 수 있게 해야 합니다.
때문에,
현재는 단순하게, 플레이어가 지나간 방과 인접한 방, 색상을 동일하게 (Gray), 현재 위치를 하얀색으로 표현했지만, 추후 확장성을 고려하여,


미니맵을 나타내는 이중배열인 roomBoard는 인트형 배열로써, 상태를 저장하는 열거형 변수로 활용할 수 있습니다.
최초 이중배열을 0으로 초기화한 후에.
이후, 방이 존재한다면
roomBoard의 값을 수정하고,
추후 이중배열의 원소와의 접근성을 생각하여, 딕셔너리를 이용해서 Room 객체 변수를 이용해서 이중배열의 position 좌표값을 얻을 수 있도록 함께 Add해줍니다.
즉,
특수 아이템을 획득했을 때, roomBoard에 저장된 값을 수정하는 것으로 미니맵의 특수 기능을 구현 하는 등의 확장성을 보장할 수 있습니다.
이렇게 roomBoard 이중배열에 저장된 값들은,
렌더링 과정에서

위 코드와 같이, 색상을 다르게 하는 등으로 미니맵 출력이 가능합니다.
랜덤맵 제너레이터에 저장된 배열의 구조 그대로, 미니맵을 생성한다면.
모양 그대로 미니맵이 이식되는 것이 아니라, 반시계 방향으로 90도 꺾인 모양으로 출력되는 것을 확인할 수 있었습니다.
때문에,

다음 함수를 호출하여
이중배열을 회전하여 각도를 맞춰야 했습니다.
미니맵은 현재 Rect Mask 2D를 이용해서 그리드 레이아웃이 부모 객체(백그라운드)를 벗어나지 않도록 방지한 상태입니다.
하지만 이 경우에, 맵이 너무 커서 백그라운드를 벗어날 수밖에 없는 상황인데.
플레이어가 이동을 이어갈 경우,
미니맵의 출력 범위를 벗어나는 문제가 발생합니다.
때문에, 플레이어의 이동에 맞춰, 그리드 레이아웃 객체를 이동시키고
최초 미니맵 생성 시에,
정중앙에 플레이어의 시작 방이 위치하도록 보정해야만 했습니다.
보정을 하지 않을 경우에,
그리드 레이아웃은 계속 이동하는데,
플레이어의 위치는 미니맵 바깥에 존재하는 예외 상황이 발생할 수 있습니다.
처음 중앙 위치 맞추기를 구현하고자 했을 때,
아이디어는 아래와 같았습니다.
미니맵 아이디어
step1
생성된 이중배열의 정중앙 값이 미니맵 오브젝트의 정중앙에 오도록 보정
Step2
보정된 값에, start room의 위치값만큼 좌표를 수정 정중앙보다 작은 값이면 감산, 큰값이면 증산
그리고 실제 구현 과정에서도
위 스탭과 유사한 흐름을 거쳐서,
중앙으로 맞출 수 있었습니다.

레이아웃 컴포넌트의 RectTransform을 가져와서,
roomBoard 이중배열의 xy 길이에 cell Size를 곱하여, 중앙에 맞추기 위한 보정값을 구하고
이를 그리드 레이아웃에 적용합니다.

그리고나서,
현재 방(startRoom)의 좌표를 가져와서,
딕셔너리를 참조하여 이중배열 상의 위치를 구하고
여기에 셀사이즈를 곱하여, 오프셋을 구해
감산하면
미니맵의 정중앙에 시작 위치가 오게 됩니다.
도어 프리팹에는
Door 클래스가 부착되어 있어,
방을 넘어갈 때 일어나는 모든 게임적 프로세스가 시작됩니다.
등이 이뤄집니다.

위 코드가 문 통과 시, 현재 통과한 문의 타입(방향)에 따라서 미니맵의 그리드 레이아웃의 위치를 보정하는 코드입니다.

그리고 위 코드는 미니맵을 업데이트 하는 코드입니다.
리미트 값을 새롭게 조정하고, 다음 방을 플레이어가 존재하는 방으로 업데이트 합니다.


미니맵 업데이트 함수입니다.
현재 방을 inPlayer 상태로 바꾸고,
인접한 방의 상태도 바꿔줍니다.
이후, 미니맵 렌더링 기능을 담당하는 RenderMiniMap 함수를 호출합니다.