Tilemap (1)

2D 게임의 기본 타일맵!

 

작성 기준 버전 :: 2019.1 - 2019.2

 

[이 포스트의 내용은 유튜브에서 영상으로도 시청하실 수 있습니다]

 

  

예전에 RPG메이커를 사용했을 때는 맵이 타일(Tile) 방식으로 이루어져 있어서 타일 팔레트를 가져와서 마치 그림 그리듯이 원하는 타일을 칠해주는 방식으로 맵을 만들 수 있었다.

 

유니티 엔진을 처음 배웠던 5 버전에서는 이러한 기능이 없어서 2D 맵 오브젝트를 직접 배치하거나 타일맵 기능을 직접 구현해야만 했었다. 하지만 유니티 2017.2 버전에서부터 타일맵 기능이 유니티에도 추가되었다. 맵오브젝트를 배치할 필요없이 그림 그리듯이 맵을 만들 수 있다는 것은 굉장한 장점이다. 

 

 

 

타일맵의 타일을 하나 추가해서 아래쪽 이미지와는 조금 다를 수 있다.

  

샘플용 간단한 타일맵 이미지를 다운받은 뒤, 타일맵의 사용법에 대해서 알아보자. 구글에서 적당한 리소스를 다운받아서 사용해도 좋다.

 

 

타일 팔레트(Tile Palette) 만들기

 

타일맵을 씬에 배치하기 이전에 먼저 타일맵을 색칠할 수 있는 타일의 종류를 모아둔 것을 만들어야 하는데 이것을 유니티 엔진에서는 타일 팔레트(Tile Palette)라고 부른다. 이 타일 팔레트를 만드는 방법에 대해서 배워보자.

 

타일 팔레트가 될 이미지 임포트 & 세팅

 

먼저 타일 팔레트에 들어갈 이미지를 임포트하고 타일맵에 사용하기 좋게 세팅해야 한다.

 

 

다운로드 받은 타일맵 이미지를 프로젝트에 임포트한다. 처음으로 임포트한 이미지는 대부분 설정이 위와 같을 것이다. 타일맵 이미지의 임포트 세팅을 적절하게 설정해주어야 한다. 

 

우선 Pixels Per Unit은 이미지의 픽셀을 몇 개를 단위로 유니티 엔진의 공간 상에서 1단위(유닛, Unit)로 표현할 것인가에 대한 설정이다. 유니티에서의 1단위는 보통 1m를 의미한다. 즉, 몇 개의 픽셀을 1m로 볼 것인가를 의미하는 셈이다. 타일맵 이미지를 열어서 확인 해보면 알겠지만 타일맵의 이미지는 한 칸당 128픽셀로 이루어져 있다. 한 칸을 1미터로 볼 것이기 때문에 Pixel Per Unit에 128을 입력해주자.

 

그 다음 설정은 Sprite Mode 값이다. 이 설정의 기본 값은 Single인데 이미지 한 장을 한 장의 스프라이트(Sprite)로 본다는 의미이다. 타일맵 이미지를 보면 알 수 있겠지만 타일맵 이미지는 한 장이 하나의 타일이 아니라 여러 장의 타일이 그려져 있는 것을 알 수 있다. 이 때문에 한 장의 이미지가 하나의 스프라이트가 아닌 그려진 타일의 수만큼의 스프라이트를 가져야한다는 것을 알 수 있다. 

 

 

Multiple로 설정해주자. 그 다음에는 이 이미지가 어떻게 나누어져야 하는지를 정하기 위해서 스프라이트 에디터(Sprite Editor) 버튼을 클릭한다.

 

 

 

그러면 스프라이트 에디터 창이 열리는데 기본적으로 타일맵 이미지가 하나의 스프라이트로 이루어지고 있음을 확인할 수 있다.

 

 

이미지를 여러 개의 스프라이트로 나누기 위해서 스프라이트 에디터 창의 상단 메뉴 중에서 슬라이스(Slice)를 선택하고 자동(Autometic)으로 되어 있는 타입을 Grid by Cell Count로 바꾼다.

 

 

 

그리고 컬럼(Column)과 로우(Row)를 각각 5와 3으로 변경하고 슬라이스 버튼을 누른다.

 

 

 

그렇게 하면 하나의 스프라이트로 되어 있던 타일맵 이미지가 여러 개의 스프라이트로 나누어지는 것을 볼 수 있다. 상단 바의 Apply 버튼을 누르고 적용한다.

 

 

 

프로젝트 뷰에서도 이 모습을 확인할 수 있다.

 

타일 팔레트 만들기

 

 

타일 팔레트는 상단 메뉴바에서 [Window>2D>Tile Palette] 항목을 선택한다.

 

 

그렇게 하면 위의 이미지와 같이 타일 팔레트 뷰가 열린다. 여기서 Create New Palette 버튼을 누르고

 

 

팔레트의 이름을 정하고 Create 버튼을 누른 뒤 저장하면 빈 타일 팔레트가 생성된다.

 

 

그 다음 타일로 만들고자 하는 스프라이트를 타일 팔레트로 드래그 하고 저장하면 타일맵 에셋들이 프로젝트 뷰에 생성되는 것을 볼 수 있다.

 

 

 

그리고 타일 팔레트에도 추가한 타일틀이 보여지는 것을 확인할 수 있다. 여기서 이 원하는 타일을 선택하고 씬에 배치된 타일맵에 타일을 그리면 된다.

 

 

타일맵 생성

 

 

우선 타일맵을 생성하기 위해서는 Create>2D>Tilemap을 선택하면 된다. 이 생성 과정의 경우에는 하이어라키(Heirarchy) 뷰에서 우클릭을 하거나 하이어라키 뷰 상단의 Create 메뉴 버튼, 혹은 상단 메뉴바의 GameObject 메뉴를 선택해서도 똑같이 만들 수 있다.

 

 

타일맵을 생성하면 위의 이미지와 같이 게임씬에 타일맵을 그리기 쉽게 격자선을 그려주는 그리드(Grid) 컴포넌트가 부착된 게임 오브젝트가 생성된다.

 

 

그리고 자식 게임 오브젝트로는 타일맵 컴포넌트(Tilemap Component)와 타일맵 렌더러 컴포넌트(Tilemap Renderer Component)가 부착된 게임 오브젝트가 생성된다. 앞서 만든 타일 팔레트에서 타일을 선택해서 이 타일맵 게임 오브젝트에 타일을 그려서 게임 맵을 만들면 된다. 그리드 아래에 여러 타일맵 게임 오브젝트를 넣어서 여러 층의 타일맵을 겹쳐서 맵을 만들 수도 있다.

 

타일맵 그려보기

 

 

 

타일맵이 만들어졌으면 타일 팔레트에서 타일을 선택해서 맵을 그려보자. 클릭하고 드래그하면 맵이 손쉽게 그려진다. 그리고 시프트(Shift) 키를 누르고 클릭 & 드래그하면 그려진 타일들이 지워진다.

 

 

 

추가로 [ ] 대괄호 키를 누르면 타일을 회전시킬 수 있다.

 


 

Tilemap (1) - 2D 게임의 기본 타일맵!

Tilemap (2) - 룰 타일로 타일맵 자동 연결하기

Tilemap (3) - 타일맵에 콜라이더 추가하기

반응형
  1. 익명 2020.12.22 15:49

    비밀댓글입니다

UI 비법서 (3) 

군무는 칼같은 각이 생명! Layout Group

 

작성 기준 버전 :: 2019.1 - 2019.4

 

[이 포스트의 내용을 유튜브 영상으로도 시청하실 수 있습니다]

 

UI를 구성할 때, 아무 위치에나 배치되는 경우는 거의 없다. 대부분의 UI는 미리 설계된 레이아웃에 따라서 배치된다. 대부분의 UI 혹은 메인 메뉴 같은 UI는 고정된 위치에 배치되고 그것이 추가/삭제되는 등의 변동이 실시간으로 일어나지는 않는다.

 

하지만 카드 수집형 게임(TCG) 같은 게임에서 자신이 보유한 카드를 보여주는 형식의 카드 인벤토리 UI를 예시로 들자면, 보유하고 있는 카드의 숫자에 따라서 보여주는 카드 UI의 숫자가 달라질 것이다. 카드를 새로 얻으면 가지고 있는 카드 UI들 끝에 새로 얻은 카드 UI가 바로 앞 카드 UI와 일정한 간격을 두고 생성되어야 한다. 그리고 카드를 이름이나 카드의 성능 등 사용자가 원하는 기준에 따라서 정렬하고자 하면 현재 보여주고 있는 카드 UI들을 기준에 맞춰 재정렬한 뒤에 보여주는 줘야한다. 이렇듯이 고정된 UI와 달리 실시간으로 UI를 추가/삭제하고 순서를 변동하는 작업을 필요로 한다.

 

실시간 카드 추가/제거 및 정렬을 위한 기능을 수동으로 직접 구현 한다면 상당히 많은 작업을 해야하고 시간 역시 많이 소모될 것이다. 이런 UI의 위치를 자동으로 맞춰주는 기능을 구현하는데 소모되는 시간을 줄여주기 위해서 유니티 엔진에서 제공하는 기능이 바로 레이아웃 그룹(Layout Group)이다.

 

『성능 최적화를 위해서는 사실 해당 기능을 직접 구현하는 것이 좋다. 레이아웃 그룹의 성능 문제는 본 포스트의 제일 하단에 언급되어 있다.』

 

 

 

 

 

레이아웃 그룹(Layout Group)

 

레이아웃 그룹은 UI를 자동으로 정렬하는 컴포넌트이다. 이 컴포넌트의 종류로는 수직 레이아웃 그룹(Vertical Layout Group), 수평 레이아웃 그룹(Horizontal Layout Group), 그리드 레이아웃 그룹(Grid Layout Group)이 있다.

 

  

 

수직 레이아웃 그룹(Vertical Layout Group)

 

수직 레이아웃 그룹은 주로 리스트 형식으로 UI들을 보여줄 때 사용된다. 

 

  

수직 레이아웃 그룹 컴포넌트를 사용하면 위의 이미지와 같이 하이어라키에서 자식 게임오브젝트로 들어온 UI들이 수직으로 자동 정렬된다. 이 때 캔버스에 표시되는 순서는 하이어라키에 표시된 순서와 같다.

 

 

하이어라키 창에서 Vertical Layout Group 게임오브젝트 아래에 있는 Image 게임오브젝트를 복사하면 복사/생성된 이미지 UI 게임오브젝트들이 자동으로 정렬되는 것을 확인할 수 있다.

 

 

수직 레이아웃 그룹의 프로퍼티는 위의 이미지에서 볼 수 있듯이 패딩(Padding), 스페이싱(Spacing, 간격), 차일드 얼라인먼트(Child Alignment, 자식 정렬), 컨트롤 차일드 사이즈(Control Child Size, 자식 크기 조절), 유즈 차일드 스케일(Use Child Scale, 자식 크기 사용), 차일드 포스 익스팬드(Child Force Expand, 자식 강제 확장)가 있다.

 

 

패딩(Padding)

 

 

콘텐츠 사이즈 피터를 사용하면 패딩 프로퍼티에 대해서 더 잘 이해할 수 있다. 좌 우 위 아래의 패딩 값을 조절을 하면 Vertical Layout Group 게임 오브젝트의 넓이와 높이가 늘어나며 Vertical Layout Group 게임오브젝트 아래에 있는 자식 게임오브젝트들을 감싸는 공간이 생기는 것을 확인할 수 있다.

 

 

스페이싱(Spacing)

 

 

스페이싱 프로퍼티는 자식 게임오브젝트 사이의 간격을 의미한다.

 

 

차일드 얼라인먼트(Child Alignment)

 

 

차일드 얼라인먼트는 수직 레이아웃 그룹 컴포넌트가 부착된 게임오브젝트 내부에서 어느 위치를 중심으로 콘텐츠들을 정렬할 것인가를 의미한다. 위의 이미지에서도 볼 수 있듯이 회색 사각형은 Vertical Layout Group 게임오브젝트의 영역인데, 차일드 얼라인먼트의 값에 따라서 차일드 게임 오브젝트들의 위치가 변하는 것을 확인할 수 있다.

 

 

 

 

컨트롤 차일드 사이즈(Control Child Size)

 

컨트롤 차일드 사이즈 프로퍼티는 단독으로는 큰 의미를 가지지 않는다.

 

 

하지만 위의 움직이는 이미지에서 볼 수 있듯이 컨트롤 차일드 사이즈 프로퍼티만 단독으로 사용할 때는 아무런 반응이 없었지만 차일드 포스 익스팬드 프로퍼티와 함께 사용하면 레이아웃 그룹 컴포넌트가 부착된 게임오브젝트의 사이즈만큼 하위 UI들의 크기가 커지는 것을 확인할 수 있다.

 

 

혹은 레이아웃 그룹의 하위에 속하는 요소들이 레이아웃 엘리먼트(Layout Element, 레이아웃 요소) 컴포넌트를 가지는 경우에도 의미를 가지고 동작한다.

 

 

위의 움직이는 이미지에서 레이아웃 엘리먼트와 레이아웃 그룹의 상호작용을 볼 수 있는데 컨트롤 차일드 사이즈를 넓이 옵션만 활성화 한 뒤, 레이아웃 엘리먼트의 Preferred Width와 Preferred Height를 둘 다 활성화하고 변경했지만, 넓이만 변경되는 것을 확인할 수 있다.

 

 

차일드 스케일 사용(Use Child Scale)

 

차일드 스케일 사용 프로퍼티는 하위의 UI들을 정렬할 때, 차일드 게임 오브젝트의 스케일 값을 사용할 것인가를 정한다.

 

 

위의 예시 이미지를 보면 차일드 스케일 사용 프로퍼티를 켜기 전에는 자식 오브젝트의 크기가 바뀌어도 정렬 위치 자체는 그대로인 반면에 차일드 스케일 사용 프로퍼티를 켜면 자식 오브젝트의 크기에 따라서 정렬 위치가 바뀌는 것을 확인할 수 있다.

 

 

차일드 강제 확장(Child Force Expand)

 

차일드 강제 확장 프로퍼티는 컨트롤 차일드 사이즈 프로퍼티 설명에서 봤듯이 자식 오브젝트의 크기를 레이아웃 그룹 컴포넌트가 부착된 게임 오브젝트의 크기에 맞춰서 강제로 늘어나게 만드는 옵션이다.

 

 

 

 

수평 레이아웃 그룹(Horizontal Layout Group)

 

 

수평 레이아웃 그룹은 자기 밑에 속한 자식 UI 오브젝트들을 수평으로 정렬한다. 그리고 수평 레이아웃 그룹 컴포넌트가 가진 프로퍼티는 수직 레이아웃 프로퍼티가 가진 것과 동일하며 그 기능 역시 같다.

 

 

그리드 레이아웃 그룹(Grid Layout Group)

 

 

그리드 레이아웃 그룹은 하이어라키 뷰에서 자식으로 속한 UI 게임 오브젝트들을 바둑판식으로 정렬한다. 그리드 레이아웃이 가지는 프로퍼티는 패딩(Padding), 셀 크기(Cell Size), 시작 코너(Start Corner), 시작 축(Start Axis), 차일드 얼라인먼트(Child Alignment), 제약(Constraint, 콘스트래인트)가 있다.

 

우선 패딩과 차일드 얼라인먼트 프로퍼티는 위의 수직/수평 레이아웃 그룹이 가지는 프로퍼티와 같은 기능이다.

 

 

셀 크기(Cell Size)

 

 

셀 크기 프로퍼티는 그리드 레이아웃 그룹에 속하는 UI들의 크기를 지정해주는데 사용된다.

 

 

시작 코너(Start Corner)

 

 

시작 코너 프로퍼티는 자식 UI를 정렬될 때 시작 위치를 정하는 기능이다. 왼쪽 위(Upper Left), 오른쪽 위(Upper Right), 왼쪽 아래(Lower Left), 오른쪽 아래(Lower Right)로 설정할 수 있으며 위치를 제대로 잡기 위해서는 차일드 얼라인먼트와 함께 사용하는 것이 좋다.

 

 

시작 축(Start Axis)

 

 

시작 축은 자식 UI를 정렬할 때, 수직으로 먼저 정렬할 것인지, 수평으로 먼저 정렬할 것인지를 정하는 옵션이다. 기본 설정은 수평이며, 수직으로 변경하면 새로 생겨난 UI는 아래쪽 행으로 추가 되며 레이아웃 그룹 컴포넌트가 부착된 게임 오브젝트의 가장 아래쪽 행까지 채우고 나면 그 다음 옆에 열을 추가하는 방식으로 정렬된다.

 

 

제약(Constraint)

 

 

그리드 레이아웃의 제약 프로퍼티는 기본적으로 플랙시블, 즉 유연성있는 상태로 설정되어 있는데 이것은 위의 이미지와 같이 2x2, 3x3, 4x4 형태로 정사각형의 정렬된다. 그리고 해당 NxN의 레이아웃이 수용할 수 있는 UI의 갯수를 넘어가면 N+1xN+1 행렬로 자동으로 확장된다.

 

 

이렇게 자동으로 행렬 모두가 확장되는 방식은 일반적인 UI에서는 쉽게 사용되지 않는다. 대부분의 경우에는 행이나 열 중 하나는 갯수를 고정시켜두고 추가하는 방식을 사용한다.

 

제약 프로퍼티를 Fixed Column Count로 선택하면 첫 번째 이미지처럼 열의 갯수를 고정시킨 채로 행을 추가해 나갈 수 있고, Fixed Row Count로 설정하면 두 번째 이미지처럼 행의 갯수를 고정시킨 채로 열을 추가해 나갈 수 있다.

 

 

정리

 

레이아웃 그룹은 이렇게 동적으로 추가/제거되는 UI를 정렬하기에 좋은 컴포넌트이다. 하지만 동적이지 않은 UI더라도 일정한 간격을 두고 배치되는 UI라면 번거롭게 위치를 일일이 계산해서 배치하는 것보다 빠르게 작업할 수 있게 도와준다.

 

또한, 레이아웃 그룹 컴포넌트는 콘텐츠 사이즈 피터스크롤 뷰와 함께 사용하면 좋다.

 


 

추가로...

 

조금 늦게 알게된 사실이지만 최적화를 위해서는 레이아웃 그룹의 사용을 자제해야 된다는 유니티 최적화 팁이 있다. 해당 내용은 레이아웃 그룹 내에서 하나 이상의 자식 요소가 변경되면 레이아웃 시스템이 변경된 것으로 인식해서 레이아웃 그룹 내의 각 UI 요소 1개마다 최소 1회의 GetComponents 호출을 수행한다고 한다. 단순 GetComponents 호출이 아닌 연속적인 GetComponents 호출이 성능에 얼마나 악영향을 끼치는지는 대부분의 개발자들 역시 인지하고 있을 것이다.

 

반응형

+ Recent posts