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) - 타일맵에 콜라이더 추가하기 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Explorer 2D Game Kit 분석 (3) 

Start 씬 해부하기 (2)

 

작성 기준 버전 :: 2019.1.4f1

 

Start 씬

 

 

지난 섹션에 이어서 Start 씬에 대한 분석을 이어나가보자.

 

 

UI

 

 

하이어라키 뷰(Hierarchy View)에서 UI로 분류된 게임 오브젝트는 스크린 페이더(Screen Fader), 이벤트 시스템(Event System), 스타트 메뉴 캔버스(Start Menu Canvas), 옵션 캔버스 마스터(Option Canvas Master)가 있다. 분류에서도 알 수 있듯이 모두 UI와 관련이 있는 게임 오브젝트들이다.

 

스크린 페이더 게임 오브젝트(Screen Fader Game Object)

 

 

스크린 페이더 게임 오브젝트에는 스크린 페이더 컴포넌트(Screen Fader Component)가 부착되어 있고 자식 게임 오브젝트로 블랙 페이더(Black Fader), 게임 오버 캔버스(Game Over Canvas), 로딩 캔버스(Loading Canvas)를 가진다.

 

스크린 페이더 컴포넌트(Screen Fader Component)

 

public class ScreenFader : MonoBehaviour

 

스크린 페이더 컴포넌트는 씬을 이동할 때, 화면을 페이드 인(fade in), 페이드 아웃(fade out) 시키는 역할을 하는 컴포넌트이다.

 

public static ScreenFader Instance

{

    get

    {

        if (s_Instance != null)

            return s_Instance;

 

        s_Instance = FindObjectOfType<ScreenFader> ();

 

        if (s_Instance != null)

            return s_Instance;

 

        Create ();

 

        return s_Instance;

    }

}

 

public static void Create ()

{

    ScreenFader controllerPrefab = Resources.Load<ScreenFader> ("ScreenFader");

    s_Instance = Instantiate (controllerPrefab);

}

 

void Awake ()

{

    if (Instance != this)

    {

        Destroy (gameObject);

        return;

    }

        

    DontDestroyOnLoad (gameObject);

}

 

스크린 페이더는 씬을 불러오거나 캐릭터의 위치를 이동시킬 때, 항상 존재해야 되는 컴포넌트이기 때문에 역시 싱글톤으로 구현되어 있다.

 

 

위 코드에는 약간의 문제점이 있는데 만약 존재하는 스크린 페이더가 없으면 새 스크린 페이더를 생성하는 Create() 함수를 보면 Resources 폴더에서 스크린 페이더 프리팹을 로드해서 인스턴스화하게 되어있지만, 프로젝트 뷰를 보면 스크린 페이더 프리팹은 Resources 폴더가 아닌 곳에 존재한다. 그렇기 때문에 만약 씬에 스크린 페이더가 없는데, 호출하면 스크린 페이더가 제대로 생성되지 않고 오류가 발생하게 된다. 이 문제를 해결하기 위해서는 SceneControl 폴더에 Resources 폴더를 만들고 ScreenFader 프리팹을 거기로 옮겨주면 문제는 해결된다.

 

기능

 

public enum FadeType{    Black, Loading, GameOver, }

public static IEnumerator FadeSceneIn ()

public static IEnumerator FadeSceneOut (FadeType fadeType = FadeType.Black)

protected IEnumerator Fade(float finalAlpha, CanvasGroup canvasGroup)

 

스크린 페이더 컴포넌트에서는 화면이 페이드 아웃/인 되는 경우를 같은 씬 내에서 텔레포트하는 Black, 씬과 씬 사이를 이동하는 Loading, 플레이어의 캐릭터가 죽어서 리스폰되는 GameOver, 이렇게 세 가지로 나누어서 정의하고 있다.

 

그리고 주요 기능을 하는 함수 3가지를 가진다. 화면이 점차 밝아지면서 씬으로 들어가는 효과를 주는 FadeSceneIn(), 화면이 점차 어두워지면서 씬에서 빠져나오는 효과를 주는 FadeSceneOut(), 그리고 Fade() 함수는 FadeSceneIn() 함수와 FadeSceneOut() 함수 양쪽에서 호출되는 내부 함수로 화면을 밝게 하거나 어둡게하는 효과를 처리한다.

 

이런 식으로 씬 로드를 처리할 때, 별도의 로딩 씬을 만들지 않고, UI로 덮어씌우는 방식을 커튼식 로딩 UI로 분류할 수 있다. 다만 유니티 콘텐츠 팀에서는 로딩 UI와 씬 로딩 기능을 합치지 않고, 씬을 로딩하는 씬 컨트롤러와 UI를 덮어씌우는 스크린 페이더로 분리시켜두었다. 이렇게 함으로써 스크린 페이더를 활용할 때 씬을 이동하는 경우 뿐만 아니라 씬 내부에서 텔레포트를 할 때도 스크린 페이더를 사용할 수 있게 활용도를 높일 수 있었다.

 

자식 오브젝트들(Child Objects)

 

 

스크린 페이더의 기능에 대해서 알아보았으니 이제 스크린 페이더 게임 오브젝트의 자식 게임 오브젝트들에 대해서 확인해보자. 스크린 페이더의 자식 게임 오브젝트는 블랙 페이더(Black Fader), 게임 오버 캔버스(Game Over Canvas), 로딩 캔버스(Loading Canvas), 이렇게 3개이며, 앞선 스크린 페이더 컴포넌트 분석에서 봤듯이 블랙 페이더는 같은 씬 내에서 텔레포트로 이동할 때 보여질 UI, 게임 오버 캔버스는 캐릭터가 죽어서 리스폰 될 때 보여질 UI, 로딩 캔버스는 다른 씬으로 이동할 때 보여질 UI이다. 각 자식 오브젝트들은 UI를 구성할 이미지들을 자식 오브젝트로 가지며 각각의 화면 구성은 아래와 같다.

 

블랙 페이더
게임 오버 캔버스
로딩 캔버스

 

각자 구성하고 있는 이미지들은 다르지만, 이 자식 오브젝트들은 UI를 그릴 각각의 캔버스를 각자 가지며 자식 이미지들을 한꺼번에 컨트롤할 캔버스 그룹을 컴포넌트를 가진다.

 

여러 UI들을 하나의 캔버스 밑에 두지 않는지 의아해할 수도 있다. 하지만 모든 UI를 하나의 캔버스 아래에 두면 UI의 덩어리가 커져서 관리가 힘들어질 뿐만 아니라 유니티에서는 UI를 그릴 때, 캔버스 안의 UI 요소가 하나라도 변경되면 해당 UI 요소가 속한 캔버스의 모든 UI가 다시 그려지기 때문에 성능 면의 문제가 발생할 수 있다. 그렇기 때문에 UI를 구성할 때는 적절한 기능 단위로 UI를 묶어서 캔버스를 구성하는 것이 좋다.

 

그리고 캔버스 그룹은 UI 게임 오브젝트 하위에 속하는 자식 UI들을 한꺼번에 통제해야할 때 유용하게 사용된다. 여기서는 캔버스 아래에 있는 여러 이미지 들의 알파 값을 한꺼번에 조절해서 UI를 투명하게 하거나 그 반대의 작업을 하고자 사용되었다.

 

 

스타트 메뉴 캔버스(Start Menu Canvas)

 

 

스타트 메뉴 캔버스는 Start 씬에 제일 전면에 기본적으로 깔려 있는 UI 캔버스이다.

 

 

스타트 메뉴 캔버스에는 플레이어 인풋 컴포넌트(Player Input Component), 스타트 UI 컴포넌트(Start UI Component), 메뉴 액티비티 컨트롤러 컴포넌트(Menu Activity Controller Component)가 부착되어 있으며, UI 요소 들로는 배경 화면과 UI를 구분 짓기 위한 백그라운드 틴트 이미지와 메뉴를 구성하는 제목, 메뉴판 등의 이미지 그리고 메뉴 기능을 동작시키는 버튼을 가진다.

 

이 중에서 플레이어 인풋 컴포넌트는 이 씬에서 처리하는 작업이 없고 단지 옵션에서 플레이어에게 키를 알려주기 위해서 존재하기 때문에 게임 씬에서 분석하기로 하고 지금은 넘어가도록 한다. 그리고 메뉴 액티비티 컨트롤러 역시 사실상 하는 기능이 없는 상태이기 때문에 여기서는 넘긴다.

 

스타트 UI 컴포넌트(Start UI Component)

 

public class StartUI : MonoBehaviour 

{

    public void Quit()

    {

#if UNITY_EDITOR

        EditorApplication.isPlaying = false;

#else

Application.Quit();

#endif

    }

}

 

스타트 UI 컴포넌트 역시 크게 하는 일은 없다. UI 중에 EXIT GAME 버튼이 눌렸을 때 호출될 이벤트만 구현되어 있다. 여기서 볼만한 점은 유니티 에디터에서 실행되었을 때는 에디터의 isPlaying을 false로 만들어서 플레이를 중지시키고 빌드된 상황에서는 어플리케이션을 종료하도록 UNITY_EDITOR 심볼을 통해서 정의되어 있다는 점이다. 이런 식의 조건부 컴파일 방법은 정해진 심볼에 따라 특히 유니티에서는 빌드하고자 하는 플랫폼이나 운영체제에 따라 실행될 코드를 분리할 수 있다는 점이다.

 

조건부 컴파일에도 역시 단점과 주의해야할 점이 분명이 있다. 비주얼 스튜디오 기준으로 활성화되지 않은 심볼의 코드는 회색으로 표시되며 활성화되지 않는다. 그 때문에 인텔리센스 역시 동작하지 않으며, 이 구간에서는 자동완성을 지원하지 않는다. 때문에 신텍스 에러가 발생하지 않도록 주의해야 하며, 한 조건부 코드에 로직 변경이 발생했을 때, 다른 조건부 코드에도 까먹지 말고 변경된 로직을 적용해주어야 한다. 

 

조건부 컴파일을 사용하면 세심하게 관리해야할 코드가 늘어난다. 수정사항이 발생했을 때 활성화된 코드와 비활성화된 코드를 제대로 바꿔주지 않으면 에러가 발생하고 작업 시간과 빌드 시간이 배로 늘어날 것이다. 그렇기 때문에 가능하다면 플랫폼에 특화된 코드보다는 모든 플랫폼에서 동작하는 코드를 작성하고 불가피한 경우에만 조건부 컴파일로 코드를 나눌 것을 권장한다.

 

버튼의 사용법

 

남은 스타트 메뉴 캔버스의 요소들은 대부분 기본적인 것으로 별달리 언급할 요소가 못되지만, 시작 메뉴의 버튼들은 이야기해 볼 만한 것이 있다.

 

 

보통 유니티의 UI에서 버튼과 상호작용할 때 생기는 효과를 사용할 때는 기본적으로 색깔만 바뀌는 컬러 틴트(Color Tint)를 사용하거나 조금 더 특별한 방식으로 효과를 주고 싶을 때는 스프라이트를 교체하는 스프라이트 스왑(Sprite Swap) 기능을 주로 사용한다.

 

 

Start 씬에서 플레이를 실행하고 각 버튼에 마우스를 올려보면 작은 삼각형이 회전하는 연출이 보일 것이다. 이것은 컬러 틴트나 스프라이드 스왑만으로는 불가능한 연출이다.

 

 

스타트 메뉴 캔버스에 속한 버튼을 선택해보면 그 이유를 알 수 있는데 트랜지션(Transition)을 컬러 틴트나 스프라이트 스왑이 아닌 애니메이션(Animation)으로 설정되어 있고 별도의 애니메이터 컨트롤러가 붙어있는 것을 볼 수 있다.

 

 

각 상황마다 버튼이 실행할 애니메이션을 만들어서 이미지가 바뀌거나 색이 바뀌는 것보다 더욱 다양한 연출을 할 수 있다.

 

 

옵션 캔버스 마스터(Option Canvas Master)

 

 

옵션 캔버스 마스터는 게임의 설정을 조절하기 위한 UI들을 모아둔 캔버스로 자식 게임 오브젝트로 음향을 설정하기 위한 오디오 캔버스와 게임 플레이 조작을 위한 컨트롤 캔버스를 가지고 있다. 다만 컨트롤 캔버스의 경우, 키 변경 기능을 구현해두지 않았기 때문에 게임에서 사용하는 키를 보여주는 기능만 있다. 그리고 옵션 캔버스 마스터 자체는 캔버스 분리 이 외에는 평범하게 만들어졌기 때문에 특별하게 언급할 부분이 없다.

 

Scene Assets

 

 

스타트 씬에서 씬 에셋으로 분류해둔 게임 오브젝트들은 카메라, 포스트 프로세싱, 라이트, 그리고 씬을 꾸미는 배경 게임 오브젝트들이다.

 

원근감 연출

 

사실 씬 에셋 파트에서는 크게 조명할 부분은 없지만, 볼만한 부분은 원근감 연출에 있다.

 

 

보통의 2D 게임에서는 투영 방식(Projection)을 직교법(Orthographic)으로 설정해서 원근감이 사라지게 만드는 경우가 많다. 

 

 

 

하지만 게임 키트에서는 원근법(Perspective)으로 설정하여 카메라와의 거리에 따라서 오브젝트의 크기게 달라보이게 만들었다.

 

 

그리고 원근감을 연출하기 위한 두 번째 장치로 Start Screen Sprite Offsetter 라는 컴포넌트를 만들어서 마우스의 움직임을 감지하고 오프셋 수치에 따라서 배경에 배치된 오브젝트들이 다르게 움직이게 만들어져 있다.

 

 

잠시 화면을 가리는 스타트 메뉴를 비활성화 시키고 플레이 버튼을 눌러서 게임을 실행시킨 뒤, 마우스를 움직여보면 배경이 마우스의 움직임에 따라서 반응하여 더욱 원근감을 강하게 느낄 수 있도록 만들어주는 것을 볼 수 있다.

 

이것으로 스타트 씬에 대한 분석은 끝났고 이 다음부터는 게임 플레이와 관련된 부분을 분석해보자.

 


 

Explorer 2D Game Kit 분석 (1) - 개요

Explorer 2D Game Kit 분석 (2) - Start 씬 해부하기 (1)

Explorer 2D Game Kit 분석 (3) - Start 씬 해부하기 (2)

Explorer 2D Game Kit 분석 (4) - 게임플레이 요소 (1)

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Explorer 2D Game Kit 분석 (2) 

Start 씬 해부하기 (1)

 

작성 기준 버전 :: 2019.1.4f1

 

Start 씬

 

 

2D 게임 키트에서 제일 처음으로 분석해볼 것은 바로 Start 씬이다. Start 씬은 게임 키트에서 게임이 시작되는 메인 메뉴를 구성하고 있다. 이 씬에서 하이어라키 뷰에 게임 오브젝트들은 어떻게 배치되어 있는지, UI는 어떻게 구성하고 있는지, 그리고 스크립트들은 어떻게 짜여 있는지를 알아볼 것이다.

 

 

하이어라키 뷰(Hierarchy view)

 

 

하이어라키 뷰에서는 시작 씬에 배치된 게임 오브젝트들을 리스트 형식으로 모두 한 번에 볼 수 있다. 실제로 게임을 만들면서 씬에 게임 오브젝트들을 배치하다보면 제대로 된 정리가 이루어지지 않고 난장판이 되는 경우가 다반사이다. 그에 반해 유니티 콘텐츠 팀에서 제작한 2D 게임 키트의 경우에는 위의 이미지와 같이 깔끔하게 하이어라키 뷰를 정리해두었다.

 

 

우선 빈 게임 오브젝트를 이용하여 경계선을 지어서 분류별로 게임 시스템과 관련된 게임 오브젝트, UI 게임 오브젝트, 해당 씬에서만 사용되는 게임 오브젝트 등으로 구분해두었다. 이렇게 해둠으로써 어디에 어떤 게임 오브젝트가 있는지 일일이 찾을 필요없이 카테고리별로 빠르게 찾을 수 있게 된다. 시작 씬 이외에도 게임을 플레이하는 씬인 Zone1~5 씬이 있는데 대부분의 씬에서도 약간의 차이점은 있지만 이러한 분류를 따르고 있다. 

 

개발자 별로 자신에게 적절하거나, 팀원과 상의한 후 팀의 씬 정리 규칙을 세우고 그 규칙에 따라 게임 오브젝트를 배치한다면 한결 보기 좋게 씬을 관리할 수 있다. 

 

 

System

 

하이어라키 뷰에서 시스템으로 분류된 게임 오브젝트는 씬 컨트롤러(Scene Controller), 트랜지션 스타트(Transition Start), 백그라운드 뮤직 플레이어(Background Music Player)가 있다. 시스템 쪽으로 분류해둔 게임 오브젝트들은 게임 시스템과 관련된 오브젝트이며, 대부분 모든 씬에서 존재해야되는 오브젝트들이 많다.

 

씬 컨트롤러 게임 오브젝트(Scene Controller Game Object)

 

 

씬 컨트롤러 게임 오브젝트에는 씬 컨트롤러 컴포넌트와 씬 컨트롤러 래퍼 컴포넌트가 부착되어 있다. 우선 씬 컨트롤러 컴포넌트는 다른 씬을 불러오는 씬 로드 기능을 관리하고 있으며 씬 컨트롤러 래퍼 컨트롤러 컴포넌트는 씬 컨트롤러 컴포넌트를 감싸는 역할을 한다(이 감싸는 역할이란 무엇인가는 잠시 후에 설명하도록 하겠다).

 

씬 컨트롤러 컴포넌트(Scene Controller Component)

 

public class SceneController : MonoBehaviour

 

씬 컨트롤러 컴포넌트는 앞서 이야기 했듯이 다른 씬을 불러오는 씬 로드 관리를 담당하는 컴포넌트이다. 

 

protected static SceneController instance;

 

public static SceneController Instance

{

    get

    {

        if (instance != null)

            return instance;

 

        instance = FindObjectOfType<SceneController>();

 

        if (instance != null)

            return instance;

 

        Create ();

 

        return instance;

    }

}

 

public static SceneController Create ()

{

    GameObject sceneControllerGameObject = new GameObject("SceneController");

    instance = sceneControllerGameObject.AddComponent<SceneController>();

 

    return instance;

}

 

void Awake()

{

    if (Instance != this)

    {

        Destroy(gameObject);

        return;

    }

 

    DontDestroyOnLoad(gameObject);

 

    m_PlayerInput = FindObjectOfType<PlayerInput>();

 

    if (initialSceneTransitionDestination != null)

    {

        SetEnteringGameObjectLocation(initialSceneTransitionDestination);

        ScreenFader.SetAlpha(1f);

        StartCoroutine(ScreenFader.FadeSceneIn());

        initialSceneTransitionDestination.OnReachDestination.Invoke();

    }

    else

    {

        m_CurrentZoneScene = SceneManager.GetActiveScene();

        m_ZoneRestartDestinationTag = SceneTransitionDestination.DestinationTag.A;

    }

}

 

씬 컨트롤러 컴포넌트에서 제일 먼저 살펴볼 부분은 이것이다. 씬을 불러오는 기능은 모든 씬에서 존재하며 다른 씬을 불러올 수 있어야 하기 때문에 싱글톤 패턴DontDestoryOnLoad가 적용되어 있다.

 

protected IEnumerator Transition(string newSceneName, bool resetInputValues, SceneTransitionDestination.DestinationTag destinationTag, TransitionPoint.TransitionType transitionType = TransitionPoint.TransitionType.DifferentZone)

{

    m_Transitioning = true;

    PersistentDataManager.SaveAllData();

 

    if (m_PlayerInput == null)

        m_PlayerInput = FindObjectOfType<PlayerInput>();

    m_PlayerInput.ReleaseControl(resetInputValues);

    yield return StartCoroutine(ScreenFader.FadeSceneOut(ScreenFader.FadeType.Loading));

    PersistentDataManager.ClearPersisters();

    yield return SceneManager.LoadSceneAsync(newSceneName);

    m_PlayerInput = FindObjectOfType<PlayerInput>();

    m_PlayerInput.ReleaseControl(resetInputValues);

    PersistentDataManager.LoadAllData();

    SceneTransitionDestination entrance = GetDestination(destinationTag);

    SetEnteringGameObjectLocation(entrance);

    SetupNewScene(transitionType, entrance);

    if(entrance != null)

        entrance.OnReachDestination.Invoke();

    yield return StartCoroutine(ScreenFader.FadeSceneIn());

    m_PlayerInput.GainControl();

 

    m_Transitioning = false;

}

 

씬 컨트롤러 컴포넌트의 가장 중심 기능인 씬 로드 기능은 Transition() 코루틴 함수에 정의되어 있다. 그 외의 함수들은 씬을 다시 시작하는 함수, 목표 지점 태그로  이동할 위치를 가져오는 함수 등 부가적인 기능을 구현하고 있다.

 

씬 컨트롤러 래퍼 컴포넌트(Scene Controller Wrapper Component)

 

public class SceneControllerWrapper : MonoBehaviour

{

    public void RestartZone (bool resetHealth)

    {

        SceneController.RestartZone (resetHealth);

    }

 

    public void TransitionToScene (TransitionPoint transitionPoint)

    {

        SceneController.TransitionToScene (transitionPoint);

    }

 

    public void RestartZoneWithDelay(float delay)

    {

        SceneController.RestartZoneWithDelay (delay, false);

    }

 

    public void RestartZoneWithDelayAndHealthReset (float delay)

    {

        SceneController.RestartZoneWithDelay (delay, true);

    }

}

 

씬 컨트롤러 래퍼 컴포넌트는 씬 컨트롤러 컴포넌트를 감싸는 컴포넌트로 호출 방향을 구분하기 위해서 만들어졌다.

 

 

호출 방향의 구분의 개념은 위의 이미지와 같다. 위의 이미지에서 볼 수 있듯이 씬에 배치된 게임 오브젝트의 이벤트로 호출될 때는 씬 컨트롤러 래퍼 컴포넌트를 통해서 호출되도록 만들고, 스크립트 내부에서 호출될때는 씬 컨트롤러를 직접 호출하게 설계되어 있다. 굳이 이렇게 나누어서 설계를 할 필요가 있는가 싶겠지만, 이렇게 씬 쪽에서 호출되는 방향과 내부 스크립트에서 호출되는 방향을 구분함으로써 문제가 발생했을 때, 어느 쪽 호출에서 문제가 발생했는지 빠르게 발견할 수 있다는 장점이 있다.

 

 

트랜지션 포인트 게임 오브젝트(Transition Point Game Object)

 

 

트랜지션 포인트 게임 오브젝트는 박스 콜라이더(Box Collider)와 트랜지션 포인트(Transition Poiont) 컴포넌트를 가진 게임 오브젝트로 실제로는 박스 콜라이더에 접촉한 플레이어를 다른 씬으로 전송하는 역할을 담당하는 게임 오브젝트이다.

 

단, 현재 씬은 플레이어의 캐릭터가 존재하지 않는 메인 메뉴 씬이기 때문에, 플레이어 캐릭터 오브젝트가 박스 콜라이더에 충돌하는 상황은 존재하지 않을 것이다.

 

트랜지션 포인트 컴포넌트(Transition Point Component)

 

[RequireComponent(typeof(Collider2D))]

public class TransitionPoint : MonoBehaviour

 

트랜지션 포인트 컴포넌트는 해당 컴포넌트가 부착된 게임 오브젝트가 소유한 콜라이더 2D(Collider2D)에 접촉한 플레이어 캐릭터를 다른 지역으로 보내는 역할을 한다. 그렇기 때문에 RequireComnent 어트리뷰트를 이용해서 트랜지션 포인트 컴포넌트가 부착되는 게임 오브젝트에는 반드시 Collider2D 컴포넌트가 부착되어 있어야 함을 정의하고 있다.

 

public enum TransitionType

{

    DifferentZone, DifferentNonGameplayScene, SameScene,

}

 

public enum TransitionWhen{    ExternalCall, InteractPressed, OnTriggerEnter, }

 

그리고 트랜지션 포인트 클래스 내부에는 Transition Type과 Transition When이라는 열거형 두 가지가 정의되어 있다. Transition Type은 트랜지션 포인트가 어떤 종류의 씬으로 전환되는지를 의미한다. DifferentZone 타입은 다른 게임 플레이 씬으로 이동하는 것을 의미한다. 스타트 씬에 있는 트랜지션 포인트 역시 DifferentZone으로 설정되어 있는 것을 볼 수 있는데, 메인 메뉴 씬을 기준으로 시작 게임 씬 역시 "다른 게임 플레이 씬"이기 때문에 DifferentZone으로 설정되는 것이 맞다. DifferentNonGameplayScene 타입은 다른 씬이지만, 게임 플레이 씬은 아닌 경우이다. 예를 들자면 게임 플레이 씬에서 다시 메인 메뉴 씬으로 돌아오는 경우이다. SameScene은 같은 씬의 다른 지점으로 이동할 때를 의미한다.

 

TransitionWhen 열거형은 어느 시점에 전송을 시작할 것인가에 대한 것인데, ExternalCall은 외부에서 호출이 있을 경우를 의미한다. 앞에서 메인 메뉴에서는 플레이어 캐릭터 오브젝트가 없기 때문에 박스 콜라이더에 충돌하는 상황이 벌어지지 않을 것이라고 말했다. 그렇기 때문에 위의 이미지에서 스타트 씬의 트랜지션 포인트 게임 오브젝트에 부착된 트랜지션 포인트 컴포넌트의 Transition When의 값이 ExternalCall으로 설정되어 있는 것을 볼 수 있다. 즉, 콜라이더의 충돌을 이용하지 않는 경우라면 ExternalCall을 사용하는 것이다. InteractPressed는 플레이어 캐릭터가 트랜지션 포인트에 접촉한 상태에서 상호작용 키를 눌렀을 때를 의미한다. OnTriggerEnter 타입은 캐릭터가 트랜지션 포인트의 콜라이더에 접촉하는 순간에 바로 전송을 시작한다.

 

protected void TransitionInternal ()

{

    if (requiresInventoryCheck)

    {

        if(!inventoryCheck.CheckInventory (inventoryController))

            return;

    }

        

    if (transitionType == TransitionType.SameScene)

    {

        GameObjectTeleporter.Teleport (transitioningGameObject, destinationTransform.transform);

    }

    else

    {

        SceneController.TransitionToScene (this);

    }

}

 

트랜지션 포인트 컴포넌트에서 다른 씬으로 이동시키는 주요 기능은 TransitionInternal() 함수에서 처리하고 있으며, 여기에서 다른 씬을 로드하는 기능을 담당하는 씬 컨트롤러를 호출한다. 그리고 때에 따라서 트랜지션 타입이 SameSceme이라면 이동시키고자 하는 게임 오브젝트(예를 들어 플레이어)를 같은 씬 내의 목표 위치로 이동시키는 기능 역시 함께 담당한다.

 

프리팹화

 

트랜지션 포인트 게임 오브젝트는 파란색 육면체 아이콘을 보면 프리팹화되어 있는 것을 볼 수 있다. 이렇게 함으로써 플레이되고 있는 씬이나 캐릭터의 위치를 이동시키기 위해서 트랜지션 포인트를 일일이 만들 필요없이 트랜지션 포인트 프리팹을 원하는 위치에 가져다 놓고 프로퍼티만 설정하면 언제든 위치 이동 장치를 만들 수 있는 것으로 재활용성을 극대화했음을 알 수 있다.

 

씬 이름 활용법

 

 

이 트랜지션 포인트의 구현법 중에 가장 유용하다고 평할만한 포인트는 바로 씬 이름을 다루는 부분이다. 보통 다른 씬을 호출할 때, 씬 이름을 문자열로 호출하거나 빌드 세팅에 등록된 씬 인덱스를 이용해서 호출하는 경우가 많은데 이런 방법들은 몇 가지 문제점을 내포하고 있다. 

 

우선 씬 인덱스를 사용하는 방법은 등록된 씬의 순서가 변경되면 의도하지 않은 다른 씬이 호출되는 문제가 쉽게 발생한다.

 

그리고 일반적인 문자열을 사용하는 방식은 사용자의 오타 문제가 있을 수 있고, 특히 코드 난독화를 사용할 때, 상수 타입의 고정된 문자열을 코드에서 직접 사용한다면, 코드 난독화가 상수 문자열로 코드에 들어있는 씬 이름을 암호화해서 원하는 씬을 불러오지 못하는 경우도 발생할 수 있다.

 

그렇다면 2D 게임 키트에서는 어떻게 씬 이름을 다루어서 이런 문제를 해결했는지 살펴보자.

 

[SceneName]

public string newSceneName;

 

트랜지션 포인트 스크립트에는 해당 포인트가 플레이어를 어떤 씬으로 보낼지에 대한 변수인 new Scene Name 변수가 선언되어 있다.

 

 

일반적인 공개된 문자열이라면 인스펙터 뷰에서 위의 이미지와 같이 보여야할 것이다.

 

 

하지만 인스펙터 뷰에서 트랜지션 포인트 컴포넌트의 New Scene Name 프로퍼티를 보면 일반적인 string과는 다르게 팝업 선택 필드 방식으로 빌드 세팅에 등록된 씬 이름들을 선택할 수 있게 되어 있다. 이런 식으로 빌드 세팅에 등록된 이름을 선택하는 방식이면 등록된 씬의 순서가 변경될 때의 문제나 오타 문제, 씬 이름이 암호화될 문제 역시 발생하지 않는다.

 

[SceneName]

 

보통의 공개된 문자열과 다른 부분은 바로 이 SceneName 어트리뷰트가 붙어있다는 점이다. 바로 이 SceneName 어트리뷰트를 사용해서 이 어트리뷰트가 붙은 string은 인스펙터 창에서 인풋 필드(Input Field) 대신에 등록된 씬 이름이 드롭다운 형식으로 표현되게 만든 것이다.

 

public class SceneNameAttribute : PropertyAttribute

{}

 

SceneName 어트리뷰트를 [F12] 키로 따라가보면 씬 네임 어트리뷰트는 정의만 되어있고 내부에는 아무 것도 없다.

 

[CustomPropertyDrawer(typeof(SceneNameAttribute))]

public class SceneNameDrawer : PropertyDrawer

 

씬 네임 어트리뷰트의 실제 기능을 구현하는 코드는 씬 네임 드로워(Scene Name Drawer)에 있다. 씬 네임 드로워는 씬 네임 어트리뷰트가 부착된 프로퍼티를 인스펙터 뷰에서 어떻게 보여줄 것인가를 정의한다.

 

int m_SceneIndex = -1;

GUIContent[] m_SceneNames;

readonly string[] k_ScenePathSplitters = { "/", ".unity" };

 

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)

void Setup(SerializedProperty property)

 

씬 네임 드로워는 3개의 멤버 변수와 2개의 함수로 이루어져있는데, m_SceneIndex는 현재 인스펙터 뷰에서 선택한 인덱스를 m_SceneNames는 팝업 선택 필드에서 보여줄 씬 이름들을 담는다. 그리고 k_ScenePathSplitters는 위의 빌드 세팅 이미지에서 볼 수 있듯이 [2D Game Kit/Scene/씬이름]으로 나타나는 씬 경로를 [ / ]로 쪼개고 씬 이름만 가져오기 위해서 정의된 것이다.

 

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)

{

    if (EditorBuildSettings.scenes.Length == 0) return;

    if (m_SceneIndex == -1)

        Setup(property);

 

    int oldIndex = m_SceneIndex;

    m_SceneIndex = EditorGUI.Popup(position, label, m_SceneIndex, m_SceneNames);

 

    if (oldIndex != m_SceneIndex)

        property.stringValue = m_SceneNames[m_SceneIndex].text;

}

 

OnGUI() 함수는 에디터의 GUI가 그려질 때 호출되는 함수로, 씬 네임 드로워에서는 씬 네임 어트리뷰트가 부착된 프로퍼티의 GUI를 개발자가 정의한 대로 인스펙터 뷰에 그려주는 역할을 한다.

 

void Setup(SerializedProperty property)

{

    EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;

    m_SceneNames = new GUIContent[scenes.Length];

 

    for (int i = 0; i < m_SceneNames.Length; i++)

    {

        string path = scenes[i].path;

        string[] splitPath = path.Split(k_ScenePathSplitters, StringSplitOptions.RemoveEmptyEntries);

 

        string sceneName = "";

        if (splitPath.Length > 0)

            sceneName = splitPath[splitPath.Length - 1];

        else

            sceneName = "(Deleted Scene)";

        m_SceneNames[i] = new GUIContent(sceneName);

    }

 

    if (m_SceneNames.Length == 0)

        m_SceneNames = new[] { new GUIContent("[No Scenes In Build Settings]") };

 

    if (!string.IsNullOrEmpty(property.stringValue))

    {

        bool sceneNameFound = false;

        for (int i = 0; i < m_SceneNames.Length; i++)

        {

            if (m_SceneNames[i].text == property.stringValue)

            {

                m_SceneIndex = i;

                sceneNameFound = true;

                break;

            }

        }

        if (!sceneNameFound)

            m_SceneIndex = 0;

    }

    else m_SceneIndex = 0;

 

    property.stringValue = m_SceneNames[m_SceneIndex].text;

}

 

Setup() 함수는 OnGUI() 함수에서 m_SceneIndex가 -1일 때, 즉 프로퍼티가 선택되지 않았을 때, 호출된다. Setup() 함수는 EditorBuildSettings에서 빌드 세팅에 등록된 씬의 목록을 가져와 OnGUI() 함수에서 팝업 선택 필드에서 그릴 수 있는 GUIContent로 가공하는 역할을 한다. 이런 과정을 통해서 빌드 세팅에 등록된 씬의 이름을 가져와서 팝업 선택 필드에 넣어주는 것이다.

 

이 이야기는 분석을 진행하면서 계속 말하겠지만, 이런 씬 네임 어트리뷰트와 씬 네임 드로워를 정의함으로써 프로그래머는 약간의 귀찮음을 감수하고 추후에 발생할 수 있는 버그와 문제 등을 예방할 수 있고 더 나아가서 에디터에서 주 작업을 진행할 디자이너의 편의와 작업 효율을 향상시킬 수 있게 된다.

 

 

백그라운드 뮤직 플레이어 게임 오브젝트(Background Music Player Game Object)

 

 

백그라운드 뮤직 플레이어에는 백그라운드 뮤직 플레이어 컴포넌트(Backgroung Music Player Component)가 부작되어 있다. 이 컴포넌트는 이름 그대로 게임에서 흘러나오는 배경 음악을 관리한다.

 

백그라운드 뮤직 플레이어 컴포넌트(Background Music Player Component)

 

public class BackgroundMusicPlayer : MonoBehaviour

 

이 컴포넌트는 배경 음악을 관리하는 컴포넌트로 배경 음악 역시 모든 씬에서 흘러나와야 하기 때문에 싱글톤 패턴으로 작성되어 있다. 다만 이번 예제인 2D 게임 키트에서는 배경 음악의 변경이 거의 없기 때문에 크게 언급할 부분은 없다. 다만, 직접 내부 코드나 오디오 믹서를 사용하는 부분은 참고해 볼만하다.

 


 

Explorer 2D Game Kit 분석 (1) - 개요

Explorer 2D Game Kit 분석 (2) - Start 씬 해부하기 (1)

Explorer 2D Game Kit 분석 (3) - Start 씬 해부하기 (2)

Explorer 2D Game Kit 분석 (4) - 게임플레이 요소 (1)

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Explorer 2D Game Kit 분석 (1) 

개요

 

 

 

유니티 콘텐츠 팀에서 제작한

Explorer 

2D 게임 키트(2D Game Kit)가 지난 2018년 2월에 공개되었다. 2D 게임 키트는 아티스트나 디자이너 등의 개발자들이 코드를 직접 작성하지 않고도 아트와 게임플레이 요소 등을 손쉽게 활용해서 게임 레벨을 만들어볼 수 있게 구성된 에셋 컬렉션이다.

 

이 에셋 컬렉션에는 환경을 꾸밀 수 있는 여러 가지 스프라이트 에셋과 움직이는 플랫폼, 밀어서 옮길 수 있는 상자, 스위치, 석문을 열 수 있는 마법 열쇠 와 몬스터 등 플랫폼 게임에서 사용되는 요소들을 담고 있다.

 

해당 키트는 유니티의 에셋 스토에서 다운로드 받을 수 있다.

 

 

분석의 목적과 방향

 

유니티 콘텐츠 팀에서 제작한 2D 게임 키트는 아티스트와 디자이너 등의 개발자들이 코드 작성 작업을 제외하고 게임플레이를 쉽게 구성할 수 있게 하는 것이 목적이다. 이를 반대로 해석하면 프로그래머가 어떤 식으로 작업을 해주면 아티스트와 디자이너들이 더욱 손쉽게 게임 레벨을 구성할 수 있게 툴과 시스템을 만들 수 있는지를 배울 수 있다는 의미와 같다.

 

2D 게임 키트의 분석의 진행은 다음과 같이 이루어질 것이다. 

 

게임 키드에 포함된 씬을 하나씩 살펴보면서 어떻게 게임 오브젝트들이 배치되어 있는지, UI 구성은 어떻게 되어 있는지, 디자이너 등의 개발자가 레벨 구성을 쉽게 하도록 도와주기 위해서 어떤 식으로 코드가 구성 되었는지 등을 살펴보게 될 것이다.

 

 

Explorer 2D 게임 키트 에셋 다운로드 및 세팅

 

 

우선 게임 키트를 에셋을 설치하기 위해 빈 프로젝트를 생성한다.

 

 

에셋 스토어에서 2D Game Kit를 검색해서 다운로드받은 뒤 임포트 작업을 진행한다.

 

 

에셋 임포트가 끝나면 위의 이미지처럼 2D 게임 키트의 에셋들이 추가된다.

 

 

Start 씬을 열어보면 위와 같은 게임화면이 게임 뷰에 나타난다. 이로써 게임 키트에 대한 분석을 하기 위한 준비가 끝났다.

 

 

참고

 

Explorer 2D Game Kit 분석은 2019.1 버전을 사용할 것을 권장한다. 2019.2 버전의 유니티를 사용할 경우, 움직이는 플랫폼 발판이나 밀어서 이동 가능한 상자 오브젝트가 제대로 작동하지 않을 가능성이 높다.

 


 

Explorer 2D Game Kit 분석 (1) - 개요

Explorer 2D Game Kit 분석 (2) - Start 씬 해부하기 (1)

Explorer 2D Game Kit 분석 (3) - Start 씬 해부하기 (2)

Explorer 2D Game Kit 분석 (4) - 게임플레이 요소 (1)

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Tutorial (5)

 

유니티의 좌표계

 

작성 기준 버전 :: 2018.3.1f1

 

[본 튜토리얼의 내용은 유튜브 영상으로도 시청할 수 있습니다]

 

이번 섹션에서는 유니티의 좌표계에 대해서 알아보자.

 

 

좌표계란?

 

좌표계란 공간 내에서 특정한 위치를 나타내기 위한 방식이다.

 

어떤 공간에서 위치를 찾고자 하는 것인지 기준을 잡기 위해서 축이라는 것을 사용하는데, X라는 하나의 축을 사용하면 수직선 상에서의 점의 위치를 찾아낼 수 있게 된다.

 

 

X축과 Y축, 2개의 축을 이용하면 평면 상의 중심으로부터의 점의 위치를 알 수 있다.

 

 

X축과 Y축 그리고 Z축까지 3개의 축을 사용하면 3차원 공간 상의 점의 위치를 알아낼 수 있게 된다.

 

 유니티 엔진에서는 씬이라는 공간 안에서 오브젝트의 위치를 표현하기 위해서 좌표계를 이용한다.

 

수직선을 이용한 1차원 상의 공간을 사용하는 게임은 별로 없고 대부분은 2D 좌표계나 3D 좌표계를 사용한다.

 

 


2D 좌표계를 사용하는 게임으로는 슈퍼 마리오 브라더스를 예로 들 수 있고, 3D 좌표계를 사용하는 게임으로는 하프라이프를 예로 들 수 있다. 2D 좌표계를 사용하는 게임은 움직임이 상하좌우 또는 전후좌우로 움직임이 제한되지만 3D 좌표계를 사용하는 게임은 전후좌우 뿐만 아니라 상하의 움직임까지 가능하다.

 

 

왼손 좌표계와 오른손 좌표계

 

좌표의 축을 정하는 방법은 여러 가지가 있는데 그 중 대표적인게 바로 왼손 좌표계와 오른손 좌표계이다.

 

 

우선 오른손 좌표계는 엄지 손가락이 X축, 검지 손가락이 Y축, 중지 손가락이 Z축이라고 가정하고 엄지를 종이 위에 수직선을 그었을 때 양수의 방향, 즉 오른쪽을 향하게 하고 검지를 X축과 직교하는 위 방향으로 향하게 했을 때, 중지가 나를 바라보는 방향이 되게 XYZ축을 정의하는 방식이다. 일반적인 수학에서는 이 오른손 좌표계를 표준으로 사용한다.

 

 

그 다음 왼손 좌표계는 엄지와 검지의 방향을 오른손 좌표계와 같이 맞췄을 때 중지는 내가 바라보는 방향을 가리키게 되도록 XYZ축을 정의한다. 유니티에서는 이 왼손 좌표계를 기준으로 사용한다.

 

한마디로 왼손 좌표계와 오른손 좌표계의 차이는 Z축이 가리키는 방향이 달라진다는 것이다. 오른손 좌표계에서는 화면에서 바라보는 사람에게로 다가오는 방식으로 Z축이 가리키게 되지만, 왼손 좌표계는 화면을 바라보는 사람에게서 화면 방향으로 Z축이 가리키게 된다.

 

 

 

 

 

Y-Up과 Z-Up

 

좌표계를 정의할 때, X축은 기본적으로 첫 번째 수평 방향의 수직선을 기준으로 하기 때문에 대부분 같은 방향으로 고정되어 있다. 여기서 발생하는 문제는 두 번째 축인 Y축의 방향을 어떻게 정의하느냐이다.

 

 

여기에는 두 가지 관점이 있는데 위에서 내려다보는 시점으로 Y축을 앞으로 나가는 방향으로 정의하는 방식이 하나로, 이렇게하면 새로 추가되는 세 번째 축인 Z축이 높이 축이 되는 Z-Up 방식이 된다. 언리얼 엔진과 3D 모델링 툴인 3ds Max가 이 방식을 채택한다.

 

 

다른 방식으로는 옆에서 바라보는 시점에서 Y축을 위로 향하는 방향으로 정의하는 것이다. Y축이 높이 축이 되기 때문에 Y-Up이라고 하고 유니티 엔진은 이 방식을 채택한다.

 

 

월드 좌표와 로컬 좌표

 

바로 전 파트까지 좌표계란 무엇인지와 유니티 엔진에서는 어떤 방식의 좌표계를 채택했는지를 설명했다. 이번 파트에서 이야기할 내용은 월드 좌표와 로컬 좌표에 대한 이야기이다.

 

월드 좌표란 세상을 중심으로 어느 위치에 있느냐를 의미하는 것이고, 로컬 좌표는 나 혹은 어느 한 오브젝트를 중심으로 어느 위치에 있느냐 하는 것이다.

 

사실 실제 세상에서 세상을 중심으로 어떠한 객체가 어느 위치에 있느냐 하는 것은 그 세상의 중심이 어디인지는 사람마다 생각이 다르고 절대적이라고 할 수 있는 중심이 없기 때문에 세상의 중심을 기준으로 한 위치라는 것은 구할 수 없겠지만, 게임이나 유니티 엔진에서는 가능하다.

 

 

바로 씬 안의 의 위치가 바로 게임 안에서의 세상의 중심이 된다.

 

 

 

 

월드 좌표를 대상으로 봤을 때, 선택된 큐브는 {-6, 0, -4}의 위치에 존재한다.

 

그렇다면 로컬 좌표란 무엇인가? 왜 월드의 중심이 아닌 어느 한 오브젝트를 중심으로 위치를 측정해야하는 걸까?

 

 

 

위의 이미지를 보자. 스피어 오브젝트 하나가 월드 좌표를 설명할 때 사용했던 큐브 오브젝트보다 XZ좌표가 각각 1씩 월드의 중심에 가깝게 존재하고 있다. 큐브 오브젝트의 위치가 {-6, 0, -4}였으니, 스피어 오브젝트는 {-5, 0, -3}의 위치에 있다. 만약에 추가된 이 스피어 오브젝트를 큐브 스피어를 중심으로 공전하게 만들고 싶다면 어떻게 해야할까?

 

 

만약 월드 좌표만으로 처리하려고 한다면 위의 이미지와 같이 좌표가 복잡하게 바뀌는 것을 알 수 있다.

 

 

하지만 스피어 오브젝트를 큐브 오브젝트의 자식 오브젝트로 만들면 포지션이 월드의 중심 좌표를 기준으로한 월드 좌표인 {-5, 0, -3}이 아니라 큐브 오브젝트를 중심으로한 로컬 좌표 로 표시되는 것을 확인할 수 있다.

 

 

이렇게 하고 나면 간단하게 큐브 오브젝트를 회전시키는 것만으로도 궤도를 따라서 스피어 오브젝트가 간단하게 공전하는 것을 볼 수 있다. 물론 큐브도 함께 자전한다는 문제가 있기는 하지만 이런 문제는 간단하게 해결하고 스피어 오브젝트만 궤도를 따라서 공전하게도 만들 수 있다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

2D 스프라이트 시퀀스 애니메이션

 

애니메이션은 게임에 생동감을 불어넣어 준다. 그런 애니메이션은 2D와 3D 애니메이션으로 나누어 지는데 3D 모델에 본을 심어서 움직이는 3D 애니메이션과 달리 2D 애니메이션은 고전적으로 시퀀스 이미지를 사용해왔다(최근 들어서는 2D 이미지를 부위 별로 나누고 거기에 본을 심어서 움직이는 스파인이나 라이브 2D 같은 방식의 애니메이션도 사용된다).

 

 

시퀀스 이미지란 위의 이미지처럼 진행될 애니메이션을 이미지로 그려서 나열해 놓은 것을 의미한다. 일반적으로는 위의 이미지처럼 하나의 시퀀스 이미지를 뽑아서 가져온 뒤에 오프셋을 이동시키는 방법으로 시퀀스 애니메이션을 사용했지만 유니티에서는 시퀀스 이미지를 각 프레임별로 이미지를 잘라서 사용한다.

 

잘라서 가져온 스프라이트 이미지

 

유니티 엔진에서 스프라이트 시퀀스 애니메이션은 크게 2가지 용도로 사용이 가능하다. 하나는 2D게임을 제작할 때, 2D 오브젝트에 애니메이션을 넣는 것이고, 다른 하나는 UI에서 2D 이펙트를 주거나, 기존의 키 애니메이션이 아닌 방식으로 UI에 애니메이션을 넣고 싶을때 사용하는 것이다.

 

이 2D 시퀀스 애니메이션을 사용하는 방법은 매우 간단하다.

 

 

우선은 간단하게 시퀀스 애니메이션을 적용할 2D 스프라이트 오브젝트를 생성하자.

 

 

그리고 Hierarchy 창에서 생성한 스프라이트 오브젝트를 선택하고 애니메이션 창을 열면 해당 오브젝트에는 아직 애니메이션이 없음을 볼 수 있다. 여기서 Create 버튼을 누르면 새로운 애니메이션을 만들 수 있다.

 

 

새로운 애니메이션을 생성한 이후에 한 애니메이션에 사용될 시퀀스 이미지들을 애니메이션 창에 드래그&드롭하면 그 생성한 애니메이션 클립에 시퀀스 이미지들이 들어가면서 스프라이트 시퀀스 애니메이션이 완성된다. 참고로 1프레임당 시퀀스 이미지 1장이 들어가기 때문에 적당한 속도로 애니메이션을 출력하기 위해서는 애니메이션의 속도 조절을 해야할 것이다. 다음 이미지가 0.5배속으로 만든 스프라이트 애니메이션이 적용된 모습이다.

 

 

2D 스프라이트 시퀀스 애니메이션을 사용할 때,시퀀스 이미지의 프레임이 늘어나면 애니메이션이 부드러워 보이고 퀄리티가 높아지지만 그만큼 더 많은 리소스를 사용하게 된다는 점을 기억해야 한다.

 

또한 시퀀스 애니메이션 작업을 할 때는 애니메이션에 사용되는 시퀀스 이미지들을 한꺼번에 선택해야 하는 경우가 많은데, 만약 시퀀스 이미지들의 해상도가 높거나 이미지들의 개수가 너무 많은 경우, 이미지들을 선택하는 것만으로도 유니티 엔진이 버벅대는 사태가 발생할 수 있다.

 

유니티 엔진의 Project 뷰에서 다량 혹은 고해상도의 이미지를 선택해야하는 작업의 경우에는 Inspector 뷰 우측 상단의 자물쇠 표시를 눌러서 잠궈주고, 하단의 프리뷰 창을 내려주는 것이 많은 도움이 될 것이다.

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts