UI 비법서 (5) 

캔버스의 분할


작성 기준 버전 :: 2019.2


유니티에서 모든 UI는 캔버스(Canvas) 위에서 그려진다. 아직 유니티 엔진을 이용한 개발에 익숙하지 못한 개발자들은 모든 UI를 한 캔버스에 만드는 경우가 많다.


하지만 모든 UI를 한 캔버스로 몰아넣으면 모든 UI를 그리는 과정에서 불필요한 낭비가 발생하게 된다.


[그림 1]

 

[그림 1]을 보면 하나의 캔버스 안에 여러 개의 이미지가 포함되어 있는 것을 볼 수 있다. Checker 오브젝트는 흰 색과 검은 색으로 이루어진 이미지이고, 그 뒤에 Background Slide라는 이름의 회색 이미지가 크게 배치되어 있다.


[그림 2]

 

우선 이 상태에서 UI는 어떤 과정을 통해서 그려지는지 확인하기 위해서 프레임 디버거(Frame Debugger)를 실행해보자. 프레임 디버거는 게임에서 각 프레임이 그려질 때 어떤 과정을 거쳐서 그려지는지 보여주는 디버깅 툴이다. 이것을 통해서 어떤 렌더링 과정에서 시간을 소모하는지를 확인할 수 있는 좋은 도구이다. 프레임 디버거를 실행하기 위해서는 유니티 상단 메뉴에서 [Windows > Analysis > Frame Debugger]를 선택하면 된다.


[그림 3]


그러면 [그림 3]과 같은 프레임 디버거 창이 열린다.


[그림 4]

 

프레임 디버거 창을 띄운 후, 플레이를 시작하고 프레임 디버거 창의 Enable 버튼을 누르면 한 프레임이 그려지는데 어떤 과정으로 몇 단계나 거쳐서 실행되는지 확인할 수 있다.


[그림 5]

 

이 상태에서 7 of 7 옆에 있는 넘기기 버튼을 눌러서 확인해보면 총 7단계를 거쳐서 화면이 그려지고 있고 그 중에 UI는 6, 7단계 두 단계를 거쳐서 먼저 회색 바탕이 그려지고 그 위에 체크 무늬 이미지가 그려지는 것을 볼 수 있다.


using UnityEngine;

using UnityEngine.UI;


public class FillingImage : MonoBehaviour

{

    private Image image;


    void Start()

    {

        image = GetComponent<Image>();

    }


    bool isFill = false;

    float timer = 0f;


    void Update()

    {

        if(timer >= 1f)

        {

            timer = 0f;

            isFill = !isFill;

        }

        timer += Time.deltaTime;

        image.fillAmount = isFill ? timer : 1f - timer; 

    }

}

 

그렇다면 이번에는 회색 바탕의 이미지인 Background Slide 오브젝트에 위와 같은 코드를 추가해서 이미지가 계속해서 채워졌다가 사라지는 동작을 반복하도록 만들어보자.


[그림 6]


코드를 모두 작성했다면 Background Slide 게임 오브젝트에 컴포넌트로 붙여준다.


[그림 7]

 

이것을 실행해보면 [그림 7]와 같이 보여진다. 하지만 단순히 겉으로만 보이는 상황으로는 어떤 낭비가 발생하는지 알 수 없다. 그러면 어떤 낭비가 발생하는지 확인하기 위해서 다시 프레임 디버거로 살펴보자.


[그림 8]

 

프레임마다 분명 7단계였던 렌더링 과정이 회색 이미지가 체커와 겹치게 되면서 8단계로 늘어나는 것을 볼 수 있다.


[그림 9]

 

이 8단계로 늘어난 렌더링 과정을 살펴보면 7단계일 때는 분명 회색 바탕을 먼저 그리고 체크 무늬 이미지를 그렸던 과정이 회색 바탕과 겹치지 않은 체크 무늬 이미지를 그리는 과정, 회색 바탕 이미지를 그리는 과정 그리고 회색 바탕과 겹친 체크 무늬 이미지를 그리는 과정으로 나누어진 것을 볼 수 있다. 이것은 렌더링 과정이 아주 작게 늘어난 예시로, UI 캔버스의 구조가 복잡해지면 복잡해질 수록 어떤 성능의 낭비를 가져올지 알 수 없게 된다.


이것을 해결하기 위한 방법이 바로 이번 글의 주제인 캔버스의 분할이다.


[그림 10]

 

[그림 10]을 보면 매 프레임 변동이 발생하는 Background Slide와 늘 고정되어 있는 Checker를 다른 캔버스로 나누어 배치한 것을 볼 수 있다.


[그림 11]

 

이렇게 캔버스를 분할한 뒤 다시 실행해서 매 프레임의 렌더링 단계를 살펴보면 다시 7단계로 줄어든 것을 확인할 수 있다.


[그림 12]

 

렌더링 단계 역시 살펴보면 회색 바탕을 먼저 그리고 회색 바탕과 체크 무늬 이미지가 겹치는 것과 상관없이 한꺼번에 체크 무늬 이미지를 그리는 것을 볼 수 있다.


이렇게 캔버스를 분할하는 것 역시 렌더링 최적화를 위한 하나의 방법이 될 수 있다. 가능하면 변동되는 타이밍이 비슷한 UI끼리 그룹을 지어서 캔버스로 묶는 것이 좋다.

반응형

+ Recent posts