상세 컨텐츠

본문 제목

[Unity] 유니티 한글, 영어, 일본어, 중국어 등 아시아 Font 처리 관련

게임엔진관련/유니티 엔진

by AlrepondTech 2019. 3. 21. 18:18

본문

반응형

 

 

 

 

 

 

=======================

=======================

=======================

 

 

 

 

 

 

 

 

 

출처: https://docs.unity3d.com/kr/current/Manual/class-Font.html

 

 

폰트

 

폰트 는 GUI Text 또는 Text Mesh 컴포넌트 에서 사용할 수 있도록 생성하거나 임포트할 수 있습니다.

폰트 파일 임포트

프로젝트에 폰트를 추가하려면 폰트 파일을 에셋 폴더에 넣으면 됩니다. Unity에서 자동으로 폰트가 임포트됩니다. 지원되는 폰트의 포맷은 TrueType 폰트(.ttf 파일)와 OpenType 폰트(.otf 파일)입니다.

폰트의 Size 를 변경하려면 Project View 에서 해당 폰트를 강조하고 Inspector 의 Import Settings 에서 옵션을 선택하면 됩니다.

폰트 임포트 설정
폰트 임포트 설정
프로퍼티: 기능:
Font Size 모든 워드 프로세서에 설정된 크기를 기반으로 한 폰트 크기입니다.
Rendering mode 폰트 렌더링 모드로 Unity가 글리프에 스무딩을 적용하는 방식을 알려줍니다.
Character 폰트 텍스처로 임포트할 폰트의 문자 집합입니다.
  이 모드를 동적으로 설정하면 Unity는 폰트 데이터를 내장하게 되며 런타임 시 폰트 글리프를 렌더링합니다(아래 참조).

동적 폰트에 해당하는 임포트 설정

프로퍼티: 기능:
Include Font Data 이 설정은 Dynamic 폰트 프로퍼티와 사용될 때 폰트 패키징을 제어합니다. 이 항목을 선택하면 TTF가 빌드의 출력에 포함되나 선택하지 않으면 최종사용자가 해당 폰트를 이미 컴퓨터에 가지고 있는 것으로 간주합니다. 폰트는 저작권 보호를 받으니 라이센스가 있거나 직접 제작한 경우에만 사용해야 합니다.
Font Names 폰트나 문자를 이용할 수 없는 경우 사용할 폴백(fallback) 폰트의 리스트입니다(아래 참조).

폰트를 임포트한 후 자동으로 생성된 에셋을 확인하기 위해 프로젝트 뷰에서 폰트를 확대할 수 있습니다. 임포트하는 동안 “폰트 머티리얼”과 “폰트 텍스처”라는 두 개의 에셋이 생성됩니다. 익숙한 다른 애플리케이션과 달리, Unity의 폰트는 텍스처로 변환되며 표시되는 글리프는 텍스처된 쿼드를 사용해 렌더링됩니다. 폰트 크기를 조정하면 생성된 텍스처의 각 글리프에 사용될 픽셀 수도 적절하게 변경됩니다. 텍스트 메시 에셋은 자동 생성된 폰트 텍스처와 함께 텍스처된 3차원 지오메트리입니다. 이런 에셋이 산뜻하게 보이도록 폰트 크기를 조정할 수 있습니다.

동적 폰트

Import Settings 내 Characters 드롭다운 메뉴를 Dynamic 으로 설정하는 경우, Unity는 모든 폰트 문자에 대해 텍스처를 미리 생성하지 않습니다. 대신, FreeType 폰트 렌더링 엔진을 사용해서 바로바로 텍스처를 생성합니다. 이는 다운로드 크기와 텍스처 메모리를 줄일 수 있다는 장점이 있으며, 특히 사용자 시스템에 일반적으로 포함되는 폰트를 사용하는 경우, 폰트 데이터를 포함할 필요가 없어 더욱 유용합니다. 또는 아시아 언어나 큰 폰트 크기를 지원해야 하는 경우, 일반 폰트 텍스처를 사용하면 폰트 텍스처가 아주 커지게 되므로 이를 활용하는 편이 좋습니다.

Unity가 동적 폰트로 텍스트를 렌더링하려고 할 때 Include Font Data 가 선택되지 않은 상태에서 폰트가 사용자 컴퓨터에 설치되어 있지 않아서 폰트를 찾을 수 없는 경우 또는 라틴어 폰트를 사용하여 동아시아 스크립트 내에서 텍스트 렌더링을 시도하거나 스타일이 지정된 볼드체/이탤릭체 텍스트를 사용하는 경우와 같이 폰트에 요청한 글리프가 포함되어 있지 않은 경우, Unity는 Font Names 필드에 각각의 폰트를 찾아 프로젝트 내의 폰트 이름과 동일한 폰트 데이터가 포함된 폰트를 찾을 수 있는지 또는 요청한 글리프가 포함된 폰트가 사용자의 컴퓨터에 있는지 확인합니다. 폴백(fallback) 폰트가 존재하지 않거나 요청한 글리프가 없을 경우, Unity는 현재의 런타임 플랫폼에 일반적으로 설치된 전세계의 다양한 폰트가 포함된 폴백(fallback) 폰트의 하드 코딩된 글로벌 리스트로 폴백합니다.

WebGL이나 몇몇 콘솔과 같은 일부 타겟 플랫폼에는 Unity가 텍스트를 렌더링하기 위해 사용할 수 있는 운영체제의 디폴트 폰트가 없습니다. 이러한 플랫폼에서는 Include Font Data 는 무시되며, 폰트 데이터가 항상 포함됩니다. 폴백(fallback)으로 사용되는 모든 폰트 역시 프로젝트에 포함되어야 하므로 국제 텍스트나 볼드체/이탤릭체를 사용해야 하는 경우, 프로젝트 내에서 필요한 문자에 해당하는 폰트 파일을 추가하고 해당 폰트를 Font Names 리스트에서 설정해서 폴백(fallback) 폰트로 어떤 것을 사용할지 지정해야 합니다. 폰트가 올바르게 설정되었다면 폴백(fallback) 폰트는 Font Importer inspector 내에 References to other fonts in project 리스트에 포함됩니다.

디폴트 폰트 에셋

디폴트 폰트 에셋은 Arial을 사용하도록 설정된 동적 폰트입니다. 만일 Unity가 컴퓨터 내에서 Arial 폰트를 찾을 수 없는 경우(설치되어 있지 않은 경우 등), Unity에 내장된 Liberation Sans 폰트를 대신 사용합니다.

Liberation Sans 폰트는 Arial과 비슷하지만 볼드체나 이탤릭체가 없으며 기본적인 라틴 문자만을 지원합니다. 따라서 스타일 지정된 텍스트나 라틴 문자가 아닌 문자는 다른 폰트로 폴백되거나 렌더링이 되지 않을 수 있습니다. 하지만 플레이어 빌드에 포함될 수 있도록 라이선스를 포함하고 있습니다.

커스텀 폰트

커스텀 폰트를 생성하려면 프로젝트 창에서 ‘Create->custom font’를 선택해야 합니다. 프로젝트 라이브러리에 커스텀 폰트 에셋이 추가됩니다.

Ascii Start Offset 필드는 Character Rects 인덱스를 시작하는 Ascii 인덱스를 정의하는 10진수입니다. 예를 들어, Ascii Start Offset 값이 0으로 설정된 경우, 대문자 A는 인덱스 65에 해당하지만, Ascii Start Offset 값이 65인 경우, 대문자 A는 인덱스 0에 해당합니다. 여기에서 Ascii Table을 참고할 수 있지만 커스텀 폰트는 10진수 아스키 번호 시스템을 사용한다는 점을 기억해야 합니다.

Tracking(추적)은 같은 행 내에서 문자 사이의 간격을 설정하고 줄 간격(Line spacing)은 행 간 간격을 설정합니다.

폰트 머티리얼을 생성하려면 우선 폰트를 텍스처로 임포트한 다음 텍스처를 머티리얼에 적용해야 합니다. 그런 다음, 폰트 머티리얼을 Default Material 섹션에 드래그해야 합니다.

Character Rects 섹션에서는 폰트의 각 문자가 정의됩니다.

Size 필드는 폰트의 문자 수를 지정합니다.

각 Element 내부에는 문자의 아스키 인덱스용 인덱스 필드가 있습니다. 이는 요소 내에서 문자를 나타내는 정수입니다.

UV 값을 계산하려면 문자들이 0에서 1사이 어디에 위치하는지 알아야 합니다. 1을 치수별 문자 수로 나누면 됩니다. 예를 들어, 폰트가 있는데 이미지 치수가 256x128이고, 가로로는 4문자, 세로로는 2문자(즉 64x64)라면 UV 너비는 0.25이고, UV 높이는 0.5가 됩니다.

UV X와 Y 값은 어떤 문자를 선택하여 너비 또는 높이 값에 문자의 열/행을 곱할지를 결정하는 것입니다.

Vert 크기는 문자의 픽셀 크기에 따라 달라집니다. 예를 들어, 문자가 각각 128x128인 경우, Vert Width와 Height를 각각 128, –128로 설정하면 문자가 적절한 비율을 가지게 됩니다. Vert Y 값은 음수여야 합니다.

어드밴스(Advance)는 이 문자의 원점에서 다음 문자의 원점까지의 올바른 수평 거리(픽셀 단위)입니다. 실제 거리를 계산할 때 추적(Tracking)과 곱합니다.

커스텀 폰트 인스펙터에 값을 입력한 예
커스텀 폰트 인스펙터에 값을 입력한 예

유니코드 지원

Unity는 유니코드를 완벽하게 지원합니다. 유니코드 텍스트는 ASCII 문자 집합에서는 일반적으로 지원하지 않는 독일어, 프랑스어, 덴마크어, 일본어 문자를 표시할 수 있습니다. 또한 폰트가 지원하는 경우에 한해 화살표나 옵션 키 등 다양한 특수 용도의 문자도 입력할 수 있습니다.

유니코드 문자를 사용하려면 Import Settings의 Characters 드롭다운 메뉴에서 Unicode 또는 Dynamic 을 선택해야 합니다. 이제 이 폰트로 유니코드 문자를 표시할 수 있습니다. GUIText 또는 Text Mesh 를 사용하는 경우, 인스펙터에서 컴포넌트의 Text 필드에 유니코드 문자를 입력할 수 있습니다.

또한 스크립팅에서 표시되는 텍스트를 설정하려는 경우 유니코드 문자를 사용할 수 있습니다. C# 컴파일러는 유니코드 기반 스크립트를 완벽하게 지원합니다. 단, 스크립트를 UTF–16 인코딩 형식으로 저장해야 합니다. 이후 해당 스크립트 내에 문자열로 유니코드 문자를 추가할 수 있으며 이들은 UnityGUI, GUIText, Text Mesh에서 원하는 대로 표시됩니다.

써로게이트 페어는 지원되지 않습니다.

폰트 색상 변경

폰트 사용 방법에 따라 표시되는 폰트의 색상을 변경하는 방법이 다릅니다.

GUIText 및 텍스트 메시

GUIText 또는 텍스트 메시를 사용하는 경우, 폰트의 커스텀 Material 을 사용하면 색상을 변경할 수 있습니다. 프로젝트 뷰에서 Create > Material 을 클릭한 후 Inspector 에서 새로 생성한 머티리얼을 선택하고 설정해야 합니다. 머티리얼에 폰트 에셋의 텍스처를 할당했는지 확인해야 합니다. 폰트 머티리얼에 빌트인 GUI/Text Shader 셰이더를 사용하는 경우, 머티리얼의 Text Color 프로퍼티에서 색상을 선택할 수 있습니다.

UnityGUI

폰트를 나타내는 데 UnityGUI 스크립팅을 사용하는 경우, 다양한 상황에서 폰트 컬러를 훨씬 더 잘 제어할 수 있습니다. 폰트 컬러를 변경하려면 Assets > Create > GUI Skin 에서 GUISkin 을 생성한 다음 특정 제어 상태에 대해 Label > Normal > Text Color 와 같이 컬러를 지정하면 됩니다. 자세한 내용은 GUI Skin 페이지를 참조하십시오.

힌트

  • 임포트된 폰트를 표시하려면 폰트를 선택하고 GameObject > Create Other > 3D Text 를 선택해야 합니다.
  • 소문자만 또는 대문자만 사용하는 경우, 생성된 폰트 텍스처 크기가 작아질 수 있습니다.

 

 

 

 

 

=======================

=======================

=======================

 

 

 

출처: http://devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=42534

 

 

NGUI말고 유니티에서 중국어폰트 지원가능하게 하고 싶은데 방법을 모르겠네요. TTF폰트 읽어들여서 할 수 있을 것 같은데

 
어떻게 안될까요? NGUI다이나믹 폰트말고도 유니티에서 있을 것 같은데, 시작한지 얼마 되지 않아서요.. 버전은 4.2버전입니다.
 
정품이구요.
 
-----------------------------------------------------------------------------------------------------------------------------------------
NGUI 이용 안해도 4.x 버전부터는 유니티 자체에서 다이나믹 폰트를 지원하지 않았나요??

 

 

 

=======================

=======================

=======================

 

 

 

출처: https://iw90.tistory.com/71

 

 

Unity Dynamic Font 사용하기


안녕하세요. Unity 개발하면서 이슈 해결 방안이 있어 이렇게 포스트를 쓰고 있습니다 .


이슈는 Unity Editor 에서는 GUIText 가 잘 나타나지만 모바일 디바이스 에서 사용하면 
dp 단위로 인해서 좌표가 바뀌고 해상도에 따라서 글자가 작아지는 문제가 있었습니다 .


그래서 이번에 4.x 버젼에서 나온 다이나믹 폰트를 사용해 보았습니다 .




다이나믹 폰트 사용 준비


1. Unity 4.0 이상 버전
2. NGUI 최신 버전(2.6.1 이상)
3. TTF 폰트 




다이나믹 폰트 사용 방법












상단의 NGUI 를 통해서 Open the Font Maker 를 선택합니다 .
그러면 아래와 같은 화면이 나타 납니다 .












Type 을 Dynamic 으로 변경 합니다 .
변경하면 이와 같은 화면이 나타납니다 .










Create the Font 를 선택합니다 .
선택하면 아래와 같이 프리팹이 만들어 지는 것을 볼 수 있습니다 .













​이제 이 프리팹을 사용할 UILabel 을 만들어 보겠습니다 . 










게임 오브젝트를 하나 생성 합니다 .
알맞게 이름을 변경후 
NGUI > Scripts > UI > UILabel 을 게임 오브젝트에 넣어 주면 되겠습니다 .










넣은 후에 Font 버튼을 선택합니다 . 
그러면 왼쪽 화면과 같이 팝업창이 나타 납니다 .
저희가 위에서 만든 프리팹을 선택 합니다 .










선택하면 이와 같이 화면이 바뀝니다 .
바뀐 화면에서 크기 조절과 text 입력 , 색 등을 변경 하면 됩니다 .










설정 변경후 씬에서는 보이지만 게임에서는 안보이는 경우 Z축 , 과 Depth 를 통해서 
조절 하면 UILabel 을 볼 수 있습니다 .


글씨가 흐리게 보이는 경우에는 프리팹의 Size 를 올리면 글씨가 선명하게 나오는 것을 볼 수 있습니다 .












출처: https://iw90.tistory.com/71 [woong's]

 

반응형

 

728x90

 

 

=======================

=======================

=======================

 

 

출처: https://jfrom.tistory.com/entry/unity-font-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

unity 글자를 표현하기 위해 비트맵 폰트를 사용했었다.

unity4부터 다이나믹 폰트를 지원하기 시작했는데 동적으로 필요한 글자들을 비트맵으로 떠서 사용하는 방식이다.

그래서 다이나믹 폰트인것 같은데 다이나믹 폰트 맵이 다 차면 새로 더 큰 맵으로 만들어서 쓴다.

- Dynamic Font의 텍스쳐 관리 방식 (출처 https://www.facebook.com/be2ls/posts/644653395565677)

맨 처음 게임이 실행되면 기본 폰트 텍스쳐 크기는 256*256이다.

여기에 글자들이 추가되면서 글자를 추가할 공간이 없을 때

256*256이 256*512, 512*512, 그 다음에는 512*1024 이런식으로 텍스쳐 크기가 증가한다.

폰트 텍스쳐에 새로운 글자가 추가되었는데 더이상 추가할 수 있는 공간이 없을 때, 사용하지 않는 글자들을 정리하고 폰트 텍스쳐를 재정렬한다.

 

다국어 지원을 하려면 다이나믹 폰트가 편할것 같다.

 

기존에 방식으로 NGUI BMFont 만드는 방법 

http://lianes.tistory.com/49법

 

NGUI에 dynamic font 사용하기

http://lianes.tistory.com/49

 

또는 새로운 uGUI에서 NGUI의 BMFont를 커스텀 폰트로 사용하는 방법

http://westhillapps.blog.jp/archives/43790545.html

일본어 번역해서 보기

 

유니티4 + NGUI + dynamic font를 사용하는 경우 모바일에서 가끔 깨지는 문제가 있는데

주로 adreno GPU를 쓰는 경우 깨지는 경우가 있다고 함

다이나믹폰트 가끔 깨진다는 문제

http://devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=39509

http://devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=33157

 

이글 2013년글로 dynamic font 텍스쳐 관리방식에 대해서 소개하고 문제 피해가는 방법 설명함

https://www.facebook.com/be2ls/posts/644653395565677

unity 4.3에서 dynamic font 관련 버그 픽스가 있었다고 함, 그 이후 해결되었는지는 확인 필요.



출처: https://jfrom.tistory.com/entry/unity-font-사용하기 [j* from us]

 

 

 

=======================

=======================

=======================

 

 

 

출처: https://lifeisforu.tistory.com/344

 

Optimizing UI Controls

 

확인 완료한 버전: 5.3 - 난이도: 고급

 

이 섹션은 특정 유형의 UI 컨트롤들을 제출하는 것에 초점을 맞춘 최적화 가이드의 섹션입니다. 대부분의 컨트롤들은 성능 관점에서 상대적으로 유사하지만, 두 가지는 게임이 출시 가능한 상태에 가까워졌을 때 많은 성능 이슈를 일으키므로 특별합니다.

 

UI Text

 

유니티의 내장 Text 컴포넌트는 래스터화된 텍스트 글리프( glyph )를 UI 내부에 디스플레이하기 위한 편한 방법입니다. 그러나 일반적으로 알지 못하는 여러 가지 동작이 존재하며, 아직까지 주로 성능 핫스팟이 됩니다. UI 에 텍스트를 추가할 때, 텍스트 글리프는 실제로는 글자 하나당 개별적인 쿼드( quad )로 렌더링된다는 점을 기억해야 합니다. 이러한 쿼드들은 글리프를 둘러싼 빈 공간의 많은 부분을 차지하는 경향이 있습니다. 이는 그것의 모양에 의존하며, 원치않게 다른 UI 요소들의 배칭을 저해하는 텍스트가 배치되는 경우가 많습니다.

 

Text mesh rebuilds

 

한 가지 주요 이슈는 UI 텍스트 메쉬를 리빌드하는 것입니다. UI 텍스트 컴포넌트가 변경될 때마다, 그 텍스트 컴포넌트는 실제 텍스트를 디스플레이하기 위해서 사용되는 폴리곤들을 재계산해야 합니다. 이 재계산은 텍스트가 변하지 않더라도 텍스트 컴포넌트나 그것의 부모 게임 오브젝트들이 단순히 disable 되거나 다시 enable 될 때도 발생합니다.

 

이러한 동작은 점수판이나 통계를 위해 많은 개수의 레이블을 디스플레이하는 UI 에서 문제가 됩니다. 유니티 UI 를 가리거나 보여주는 가장 일반적인 방법은 UI 를 포함하는 게임오브젝트를 enable/disable 시키는 것이며, 많은 개수의 텍스트 컴포넌트를 가지고 있는 UI 는 그것들이 디스플레이될 때마다 원치않는 프레임율 스파이크를 일으키게 될 것입니다.

 

이 이슈에 대한 잠재적인 우회책을 원한다면, 다음 챕터의 Disabling Canvas Renderes 를 참고하시기 바랍니다.

 

Dynamic fonts and font atlases

 

동적 폰트는 전체 문자들의 집합이 매우 많거나 런타임에 앞서 알려지지 았을 때 텍스트를 렌더링하기 편한 방법을 제공합니다. 유니티 구현에서는, 이러한 폰트들은 UI Text 컴포넌트 내에 문자들에 기반해 런타임에 글리프 아틀라스를 빌드합니다.

 

로드된 각각의 개별 폰트 오브젝트는 자신만의 텍스쳐 아틀라스를 유지할 것입니다. 심지어는 그것이 다른 폰트들과 동일한 폰트 패밀리를 사용한다고 해도 말이죠. 예를 들어, 한 컨트롤 내에서 굵은( bold ) 텍스트를 가진 가진 Arial 을 사용하고, 다른 컨트롤에서 Arial Bold 를 사용하면 동일한 결과를 산출하지만, 유니티는 두 개를 개별적인 텍스쳐 아틀라스에 유지할 것입니다 - 하나는 Arial 을 위해 다른 하나는 Arial Bold 를 위해( 역주 : 하나는 Arial 폰트를 사용하고 텍스트에 굵기 옵션을 준 것이고, 다른 하나는 Arial Bold 폰트를 사용한 것을 의미하는 듯 ).

 

성능 관점에서 볼 때, 유니티 UI 의 동적 폰트가 개별 크기, 스타일, 문자를 위해 폰트 텍스쳐 아틀라스에 하나의 글리프를 유지한다는 것을 이해하는 것이 중요합니다. 즉, 만약 UI 가 두 개의 텍스트 컴포넌트를 가지고 있고, 둘다 'A' 라는 문자를 디스플레이한다고 하면:

 

    • 만약 두 Text 컴포넌트가 같은 크기를 공유한다면, 폰트 아틀라스는 그것 안에 하나의 글리프를 가지게 될 것입니다.
    • 만약 두 Text 컴포넌트가 같은 크기를 공유하지 않는다면( 예를 들어 하나는 16 포인트이고 다른 하나는 24 포인트라면 ), 폰트 아틀라스는 서로 다른 크기의 문자 'A' 를 위해 두 개의 복사본을 가지게 될 것입니다.
    • 만약 하나의 Text 컴포넌트는 bold 이고 다른 하나는 그렇지 않다면, 폰트 아틀라스는 굵은 'A' 와 보통 'A' 를 포함하게 될 것입니다.

 

동적 폰트를 가진 UI Text 오브젝트에 아직 폰트 텍스쳐로 래스터화되지 않은 글리프가 있다면, 폰트 텍스쳐 아틀라스는 반드시 리빌드되어야만 합니다. 새로운 글리프가 현재 아틀라스에 맞다면, 그것이 추가되고 그 아틀라스는 그래픽 디바이스에 다시 업로드될 것입니다. 그러나 현재 아틀라스가 너무 작다면, 시스템은 아틀라스를 리빌드할 것입니다. 이는 두 개의 단계로 수행됩니다.

 

첫째, 아틀라스는 같은 크기로 리빌드됩니다. 이 때 현재 활성화된 UI Text 컴포넌트에 의해 보이고 있는 글리프만이 사용됩니다. 만약 시스템이 현재 사용중인 글리프들을 새로운 아틀라스에 끼워 맞추는 것에 성공한다면, 그것은 그 아틀라스를 래스터화하고 다음 단계로 진행하지 않습니다.

 

둘째, 만약 현재 사용중인 글리프 집합이 현재 아틀라스와 같은 크기의 아틀라스에 끼워 맞춰질 수 없다면, 해상도가 더 낮은 쪽을 두 배로 늘린 더 큰 아틀라스가 생성됩니다. 예를 들어 512x512 아틀라스는 512x1024 아틀라스로 확장됩니다.

 

위의 알고리즘 때문에, 동적 폰트 아틀라스는 한 번 생성되고 나면 크기가 늘어나기만 합니다. Given the cost of rebuilding the texture atlases, 리빌드 동안 반드시 최소화해야 합니다. 이는 두 가지 방식으로 수행될 수 있습니다:

 

가능할 때마다, 원하는 글리프 셋을 위해서 비-동적 폰트들과 preconfigure support 를 사용하십시오. 이는 일반적으로 제약이 잘 된 Latin/ASCII 문자들과 같은 적은 범위의 크기를 가지는 문자 집합을 사용하는 UI 들을 위해 잘 동작합니다.

 

만약 전체 유니코드 셋과 같은 극단적으로 큰 범위를 가진 문자들이 지원되어야만 한다면, 폰트는 Dynamic 으로 설정되어야만 합니다. 예측할 수 있는 성능 문제들을 피하기 위해서는, 시작시에 폰트 글리프 아틀라스를 Font.RequestCharactersInTexture 를 통해 적절한 문자들의 집합을 가지도록 미리 준비시키기 바랍니다.

 

폰트 아틀라스 리빌드는 변경되는 각 UI Text 컴포넌트들을 위해서 개별적으로 발동된다는 것에 주의하십시오. 극단적으로 많은 개수의 Text 컴포넌트들을 띄울 때는, Text 컴포넌트의 내용에서 유일한 문자들을 수집하고 폰트 아틀라스를 미리 준비해야 이득입니다. 이는 글리프 아틀라스가 새로운 글리프가 나타날 때마다 한 번씩 리빌드되지 않고 한 번만 리빌드될 수 있도록 보장해 줄 것입니다.

 

폰트 아틀라스가 리빌드될 때, 활성화된 UI Text 컴포넌트에 현재 포함되어 있지 않은 모든 문자들은, 그것들이 Font.RequestCharactersInTexture 호출의 결과로서 원래부터 아틀라스에 추가되어 있는 경우라 할지라도, 새로운 아틀라스에 제출되지 않는다는 것에도 주의하시기 바랍니다. 이러한 제한을 우회하기 위해서는, 모든 원하는 문자들이 준비되어 있는 상태로 남아 있도록 하기 위해 Font.textureRebuilt 델리케이트를 구독하고 Font.characterInfo 를 질의하십시오.

 

Font.textureRebuilt 델리게이트는 현재 문서화되어 있지 않습니다. 그것은 단일 인자를 가진 유니티 이벤트입니다. 이 인자는 그것의 텍스쳐가 리빌드되어 있는 폰트입니다. 이 이벤트의 구독자는 다음 구문을 따라야 합니다:

 

1
public void TextureRebuiltCallback(Font rebuiltFont) { /* ... */ }

 

Specialized glyph renderes

 

각 글리프 사이에 상대적으로 고정된 위치를 가지고 있는 잘 알려져 있는 글리프의 경우에는, 그들의 글리프를 디스플레이하는 커스텀 컴포넌트를 작성하는 것이 이득입니다. 이것의 예는 스코어 디스플레이가 있습니다.

 

점수를 위해, 디스플레이 가능한 문자들은 잘 알려진 글리프 셋( 숫자 0 ~ 9 )으로부터 그려지며, 지역에 따라 변하지 않고, 서로 고정된 거리로 보여집니다. 정수를 그것의 숫자로 분리하고 적절한 숫자 스프라이트를 렌더링하는 것은 상대적으로 단순합니다. This sort of specialized digit-display system can be built in a manner that is both allocationless and considerably faster to calculate, animate and display than the Canvas-driven UI Text component.

 

Fallback fonts and memory usage

 

큰 문자 셋을 지원해야만 하는 애플리케이션을 위해서는, 폰트 임포터의 "Font Names" 필드에서 많은 폰트들을 리스팅하고자 하는 마음이 듭니다. "Font Names" 필드에 리스팅된 모든 폰트들은 글리프가 주요 폰트 내에 배치될 수 없는 상황에서 대안으로 사용될 수 있을 것입니다. 폴백의 순서는 "Font Names" 필드에서 리스팅된 순서에 의해서 결정됩니다.

 

그러나 이러한 동작을 지원하기 위해서는 유니티는 "Font Names" 필드에서 리스팅된 모든 폰트들을 메모리에 로드해서 유지할 것입니다. 만약 폰트 문자 셋이 매우 크다면, 폴백 폰트에 의해 소비되는 메모리의 양이 매우 커질 것입니다. 이는 일본어 한자나 중국 문자들과 같은 그림 문자( pictographical ) 폰트를 포함할 때 자주 보이는 현상입니다.

 

Best Fit and performance

 

일반적으로, UI Text 컴포넌트의 Best Fit 설정은 절대 사용되어서는 안 됩니다.

 

"Best Fit" 는 동적으로, 이는 Text 컴포넌트의 바운딩 박스 내에 오우버플로우 없이 디스플레이될 수 있으며 구성 가능한 최소/최대 포인트 크기로 잘린, 가장 큰 정수 포인트 크기로 폰트의 크기를 조정합니다. 그러나 유니티는 디스플레이되고 있는 개별 문자의 크기별로 개별 글리프를 폰트 아틀라스에 렌더링하기 때문에, Best Fit 를 사용하면 다양한 크기의 글리프를 사용하는 아틀라스의 크기를 급격히 넘어서게 될 것입니다.

 

유니티 5.3 에서는, Best Fit 에 의해 사용되는 크기 검출이 선택적이지 않습니다. 그것은 It generates glyphs in the font atlas for each size increment tested, which further increases the amount of time required to generate font atlases. 이는 아틀라스 오우버플로우를 발생시키는 경향이 있는데, 이는 오래된 글리프가 아틀라스에서 제거되도록 만듭니다. Best Fit 계산을 위한 많은 횟수의 테스트 때문에, 이는 종종 다른 Text 컴포넌트에 의해 사용중인 글리프들을 퇴거시킬 것이고, 적절한 폰트 사이즈가 계산된 후에 적어도 한 번 더 폰트 아틀라스를 리빌드시킬 것입니다. 이러한 특정 이슈는 유니티 5.4 에서 교정되었습니다. 그리고 Best Fit 는 폰트 텍스쳐 아틀라스를 불필요하게 확장하지 않을 것이지만, 여전히 정적으로 크기가 정해진 텍스트보다는 훨씬 더 느립니다.

 

자주 사용하는 폰트 아틀라스의 리빌드는 런타임 성능을 급격히 떨어뜨릴 것이고 메모리 단편화를 일으킬 것입니다. Best Fit 로 설정된 Text 컴포넌트의 양이 많아질 수록, 이 문제가 악화될 것입니다.

 

Scroll Views

 

Fill-rate 문제 다음으로, 유니티 UI 의 스크롤 뷰는 일반적으로 두 번째 가는 런타임 성능 이슈입니다. 스크롤 뷰는 일반적으로 매우 많은 개수의 UI 요소들을 사용해 자신의 칸텐츠를 표현할 것을 요구합니다. 스크롤 뷰를 띄우는 기본적인 두 가지 접근법이 있습니다:

 

    • 모든 스크롤 뷰 칸텐츠를 표현하기 위해서 충분한 모든 요소들을 채웁니다.
    • 요소들을 풀링하여, 보여지는 칸텐츠를 표현하는 데 필요한 만큼 위치를 재조정합니다.

 

둘 다 문제를 가진 해결책들입니다.

 

첫 번째 해결책은 모든 UI 요소들을 인스턴스화기 위해서 필요한 시간을 증가시킵니다. 왜냐하면 표현해야 할 아이템이 늘어날 수록 스크롤 뷰를 리빌드하는 시간이 늘어나기 때문입니다. 한줌의 Text 컴포넌트만을 디스플레이할 필요가 있는 스크롤 뷰처럼, 스크롤 뷰 내에 요구되는 요소의 개수가 적다면, 단순함을 위해 이 기법이 선호됩니다.

 

두 번째 해결책은 현재 UI 와 레이아웃 시스템 하에서 올바르게 구현하기 위한 코드의 양이 너무 많습니다. 아래에서 나중에 두 가지 가능한 기법에 대해서 논의하도록 하겠습니다. 매우 복잡한 스크롤링 UI 에 대해서, 성능 문제를 피하기 위해서는 몇 가지 종류의 풀링 접근법이 필요합니다.

 

이러한 이슈들에도 불구하고, 모든 접근법들은 RectMask2D 컴포넌트를 스크롤 뷰에 추가함으로써 개선될 수 있습니다. 이 컴포넌트는 스크롤 뷰 뷰포트 외부에 존재하는 스크롤 뷰 요소들이, Canvas 가 리빌딩될 때 지오메트리가 생성되고 정렬되고 분석되어야 하는, drawable 요소의 리스트에 포함되지 않도록 보장해 줍니다.

 

Simple Scroll View element pooling

 

유니티 내장 Scroll View 컴포넌트를 사용하는 것의 자연스러운 이점의 대부분을 보존하면서 스크롤 뷰를 사용하는 오브젝트 풀링을 구현하기 위한 가장 단순한 방법은 하이브리드 접근법을 사용하는 것입니다:

 

UI 에 요소들을 놓기 위해서, 보이는 UI 요소들을 위한 "placeholder" 로서 Layout Element 컴포넌트를 게임오브젝트와 함께 사용하십시오. 이는 레이아웃 시스템이 스크롤 뷰의 칸텐트를 적절히 계산하도록 해 주고 스크롤바가 적절히 기능하게 해 줄 것입니다.

 

그리고 나서, 스크롤 뷰의 가시 영역의 보이는 부분에 충분히 맞게 보이는 UI 요소들에 대한 풀을 인스턴스화하고, 이것들을 위치 placeholder 들의 부모로 붙이십시오. 스크롤 뷰가 스크롤링되면, UI 요소들을 재사용해서 뷰에 스크롤된 칸텐트들을 디스플레이하십시오.

 

이는 배칭되어야 하는 UI 요소들의 개수를 지속적으로 줄이게 될 것입니다. 왜냐하면 배칭 비용은 RectTransform 의 개수가 아니라 Canvas 내의 CanvasRendere 의 개수에 기반해서만 증가할 것이기 때문입니다.

 

Problems with the simple approach

 

현재는, UI 요소의 부모가 변경되거나 이웃의 순서가 변경될 때마다, 그 요소와 그것의 하위 요소들은 갱신된 것으로 표시되며 그것들의 Canvas 가 강제로 리빌드됩니다.

 

그 이유는 유니티가 transform 의 부모를 변경하는 콜백과 이웃의 순서를 수정하기 위한 콜백을 분리하지 않았기 때문입니다. 이 이벤트들은 둘 다 OnTransformParentChanged 콜백을 부릅니다. 유니티 UI 의 Graphic 클래스의 소스( Graphics.cs )에서, 그 콜백이 구현되며 SetAllDirty 메서드를 호출합니다. Graphic 을 갱신함으로써, 시스템은 Graphic 이 다음 프레임에 렌더링되기 전에 그것의 레이아웃과 버텍스들을 리빌드할 수 있도록 만듭니다.

 

캔버스들에 스크롤 뷰 내의 각 요소에 대한 루트 RectTransform 을 할당하는 것이 가능합니다. 그러면 스크롤 뷰의 전체 칸텐츠가 아니라 부모가 변경된 요소들에 국한해서 리빌드를 할 것입니다. 그러나 이것은 스크롤 뷰를 렌더링하는 데 필요한 드로콜의 개수를 증가시키는 경향이 있습니다. 더우기, 스크롤 뷰 내부의 개별 요소들이 복잡하고 수십개의 Graphic 컴포넌트로 구성되어 있고, 특히 각 요소에 Layout 컴포넌트들이 매우 많다면, 그것들을 리빌드하는 비용은 저사양 디바이스에서 프레임율을 급격하게 떨어뜨리게 될 것입니다.

 

만약 스크롤 뷰 요소가 가변 크기를 가지지 않는다면, 레이아웃과 버텍스들에 대한 완전한 재계산은 불필요합니다. 그러나 이 동작을 피하는 것은 부모 변화나 이웃 순서 변화 대신에 위치 변화에 기반한 오브젝트 풀링 솔루션을 구현할 것을 요구합니다.

 

Position-based Scroll View Pools

 

위에서 언급한 문제들을 피하기 위해서, 오브젝트가 포함된 UI 요소들의 RectTransform 들을 단순하게 이동시킴으로써 오브젝트를 풀링하는 스크롤 뷰를 생성하는 것이 가능합니다. 움직여진 RectTransform 의 크기가 변경되지 않았다면 내용은 다시 빌드될 필요가 없으며, 이는 스크롤 뷰의 성능을 매우 개선하게 됩니다.

 

일반적으로는 이를 위해 ScrollView 의 커스텀 서브클래스를 작성하거나 커스텀 LayoutGroup 컴포넌트를 작성하는 것이 최선입니다. 후자는 일반적으로 더 단순한 솔루션이며, 유니티 UI 의 LayoutGroup 추상 기저 클래스의 서브클래스를 구현함으로써 성취할 수 있습니다.

 

커스텀 LayoutGroup 은 밑에 있는 소스 데이터들을 분석해 얼마나 많은 데이터 요소들이 디스플레이되어야 하고 스크롤 뷰의 Content RectTransform 이 적절히 리사이징될 수 있는지 판단합니다. 그리고 나서 그것은 ScrollView change event 들을 구독하고 이를 사용해 그것의 가시적 요소를 적절하게 재배치할 수 있습니다.



출처: https://lifeisforu.tistory.com/344 [그냥 그런 블로그]

 

 

 

=======================

=======================

=======================

 

 

 

* 기타관련링크

 

https://blog.nakwonelec.com/2018/03/27/%EC%96%B8%EC%96%B4-%ED%8C%8C%EC%9D%BC/

 

https://scripter.co.kr/235

 

https://dark0946.tistory.com/226

 

 

 

 

 

=======================

=======================

=======================

 

 

 

 

반응형


관련글 더보기

댓글 영역