본문 바로가기
카테고리 없음

UI 최적화 및 디테일 수정 과정

by mazayong 2025. 10. 26.

2D 비주얼 노벨 게임 프로젝트를 수정하는 과정에서 UI 관련 처리 사항들을 모아서 정리하고자 한다.

처리한 부분은 아래와 같다.

 

 

 

1. Anchor 수정

2. 동적 캔버스 누락된 씬에서 동적 캔버스 추가

3. 조건에 맞는 이미지 9slice 처리

4. 텍스쳐 패킹

5. pot/npot 변경 여부 결정

6. 후기

 

 

 

 

 

 

1. Anchor 수정 

출처 : https://it.chosun.com/news/articleView.html?idxno=2019080101208

예시 게임 화면과 같이 화면을 resize하거나, 화면의 해상도의 변화가 생겨도 게임 플레이에 영향이 없게 가장자리에 배치해야 하는 UI들이 있다. 

일단은 StartScene의 설정 버튼과 게임 시작, 불러오기, 이어하기, 나가기 등의 버튼 위치를 수정했다.

그리고 대화창 UI 설정도 수정했다.

 

 

2. 동적 캔버스 누락된 씬에서 동적 캔버스 추가

비주얼 노벨의 경우, 대사가 지속적으로 갱신되고 배경 이미지와 같은 UI들이 지속적으로 갱신된다. 그래서 한 캔버스로 통일할 경우 대사 한 줄 바뀔 때마다 전체 캔버스가 다시 렌더링되기 때문에 배경과 같은 정적 이미지는 정적 캔버스, 대화창과 선택지, 세이브 같은 플레이어와 직접적으로 상호작용하고 변화가 많은 UI는 동적 캔버스로 분리했다.

 

 

 

3. 조건에 맞는 이미지 9slice 처리

피드백을 받을 때, 영상에서 9slice 처리가 필요한 부분이 있다고 하셔서 겸사겸사 이미지 크기 조절을 최적화하기 위해 9slice를 적용했다.

권장하는 이미지의 조건은 아래와 같다.

 

* 가변 크기 UI 창 / 패널 / 버튼 : 창의 크기가 내용물에 따라 자유롭게 늘어나야 할 때, 코너의 왜곡 없이 테두리만 늘어나도록 보장하여 깔끔한 UI 유지와 이미지 용량 최소화를 얻을 수 있다.

* 반복되는 배경 요소 : 테두리 끝 부분은 고정되어 있고, 반복되는 패턴을 최소한의 이미지 조각으로 표현 가능하기 때문이다.

* 박스 형태의 테두리 : 테두리 전체 비트맵 저장이 아닌 9조각만 저장하므로 이미지 용량을 줄일 수 있기 때문이다.

 

권장하지 않는 이미지 조건을 아래와 같다.

* 복잡하거나 유기적인 이미지 : 이미지가 왜곡되기 때문이다.

* 크기가 고정된 요소 : 캐릭터 애니메이션 프레임 같이 크기가 고정되어 변경될 일이 없다. 오히려 9slice를 적용하면 런타임시 불필요한 계산이 추가된다.

* 중앙 부분에 중요한 디테일이 있는 이미지 : 중앙이 반복되거나 늘어나기 때문에 이미지가 망가진다.

* 전체 이미지가 함께 늘어나는 경우 : 이미지 전체가 비율을 유지하며 확재/축소될 때는 적합하지 않다.

 

결론적으로 중앙은 단순한 이미지에 크기 변화가 있고, 테두리만 유지하기 좋은 텍스쳐가 해당된다.

대화창, 네모 형태의 디테일이 적은 버튼, UI 슬롯 등을 수정했다.

 

 

 

4. 텍스쳐 패킹

스프라이트 아틀라스를 사용해 여러 개의 개별 이미지를 하나로 묶었다.

권장하는 이미지의 조건은 아래와 같다.

 

* 자주 함께 사용되는 이미지 : 애니메이션 프레임은 1번의 드로우콜로 처리되어 애니메이션 재생 시 성능 이득이 크고, UI는 화면에 동시에 표시되어 드로우콜 낭비를 막는다.

* 동일한 환경 요소 : 타일맵의 경우 같은 텍스쳐를 사용해 지도를 유지하므로, 타일이 많이 렌더링되어도 드로우콜은 최소한이다.

* 고정된 색상, 투명도 : 이펙트에 사용되는 작은 불꽃, 연기 입자 등은 동일한 셰이더와 렌더링 설정을 공유하므로 묶어서 처리하기 좋다.

* 잦은 로드 및 언로드 : 특정 레벨/씬에서만 사용되는 잦은 오브젝트들은 레벨 로드 시 아틀라스 전체를 한 번에 메모리에 올리고, 레벨 종료시 한 번에 내릴 수 있어서 관리가 용이하다.

 

권장되지 않는 이미지의 조건은 아래와 같다.

 

* 매우 큰 이미지 : 고화질의 배경, 대형 캐릭터 이미지 같은 경우는 아틀라스의 최대 크기 제한을 초과하거나, 아틀라스 파일 크기가 너무 커져 메모리 로드 시간과 공간이 소모된다.

* 텍스쳐 설정이 다름 : 서로 다른 텍스쳐 포맷이나 셰이더/렌더링 모드를 요구하므로 묶어도 렌더링 시 드로우콜을 분리해야 하거나 한쪽의 품질 저하가 발생할 수 있다.

* 매우 낮은 빈도 사용 : 한 번만 나오는 로고 이미지, 특정 엔딩에서만 나오는 컷씬 이미지 같은 경우 아틀라스 전체를 메모리에 로드하므로 메모리 낭비가 발생한다.

* 실행 중 동적 변경 : 실시간으로 색상이나 크기가 변경되는 동적 텍스쳐의 경우 아틀라스 내부 개별 이미지 변경이 어렵거나 변경 시 전체 아틀라스를 다시 생성해야 하므로 비효율적이다.

 

즉, 패킹을 권장하는 텍스쳐는 함께 자주 사용되며 동적 변경이 일어나지 않고, 동일한 조건을 갖고 있는 텍스쳐라 할 수 있다.

 

그래서 나는 일단 내가 작업한 불러오기 화면 UI 요소들, 설정 UI 요소들, 플레이어 이동 애니메이션 등을 설정했다.

 

플레이어 이동 애니메이션 텍스쳐를 패킹한 결과, 움직이기 시작해서 움직일 때 8~12까지 변화되는 배치 수가 7~11로 줄었다. 

그리고 세이브 데이터 슬롯 UI, 설정 UI를 합친 결과 배치 수가 16에서 10으로 줄었다. 

하나의 아틀라스에 모든 텍스쳐를 다 넣을 경우 압축 형식 혼합으로 색 번짐이 발생하거나 필요 없는 이미지까지 로드되어서 오히려 자원 낭비가 발생할 수 있다고 생각해 UI와 플레이어 아틀라스를 각각 분리했다.

 

 

 

5. pot/npot 변경 여부 결정

npot 이미지의 경우는 2의 승수가 아니기 때문에 해당 수와 가장 비슷한 값을 복사해서 가져오기 때문에 npot의 경우 텍스쳐가 2개가 생성된다. 그래서 원래 pot 형식 이미지로 설정하는게 가장 베스트지만, 현재는 프로젝트가 마무리된 상태이기 때문에 더 진행하기 어려웠다. 

그래서 pot 형식으로 변환을 고민했지만, 변환하지 않고 유지하기로 결정했다.

왜냐하면 현재 Metal, Vulkan, pc, GLES3등 현대 플랫폼은 npot 텍스쳐를 정상 지원하고, 강제로 pot으로 바꿀 경우 메모리가 증가하고 품질 손상이 발생할 수 있기 때문이다.

 

 

 

 

6. 후기

생각나는 부분들을 수정해서 고쳤는데, 프로젝트는 마감할 때는 정신이 없지만 끝나고 보면 고칠 게 계속 나오는 신비로운 무언가같다. 그치만 고친 만큼 내 공부와 내 실력이 되니까 계속 고민하면서 고쳐야겠다.