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)


반응형

+ Recent posts