한글패치 관련 짧은 글들

유니티 Textmesh 폰트 dump 대략적 분석

Snowyegret 2023. 4. 6. 19:14

테스트 대상: 유니티 Textmesh 폰트

 

유니티 폰트별 비교분석을 해보자.

기존에 문제가 됐던 게 UnityEX에서 .ufnt 형식으로 export 되었던 폰트였다.

UABEA를 통해 import ttf/otf를 했음에도 적용이 안 되던 것.

폰트 로드 후 Character를 Dynamic이 아닌 Unicode로 설정하면 .ufnt 확장자로 export가 됐었다.

 

일단, 명색이 비교분석이니 종류별로 하나씩 폰트를 빌드하고,

마지막으로 UnityEX와 UABEA가 어떤 데이터를 추가하는지 알아보기 위해

UnityEX/UABEA용 Unicode 폰트를 추가해서 빌드보자. (총 8개)

 

UnityEX를 통해 봤을 때의 모습이다. Dynamic 폰트만 FontTTF라고 보이고, 나머지는 FontRAW라고 보인다.

 

UnityEX로 추출했을 때의 모습이다.

Dynamic만 ttf 폰트가 그대로 추출되고, 나머지는 ufnt 형식이다.

또한, ufnt 폰트들 중 Unicode로 설정한 폰트들만 용량이 크고, Ascii계열은 용량이 작다.

하지만 Unicode로 설정한 폰트들도 원본 폰트보단 용량이 훨씬 적다.

 

 

UABEA로 넘어가, 폰트를 덤프떠보자.

당연하겠지만, 위에서 봤던것과 같은 결과이다.

14글자를 넣은 Custom < Ascii시리즈 < Unicode < Dynamic(ttf)이다.

 

용량 순으로 파일을 열어서 주목할만한 곳이 있나 보자.

 

 

 

Dynamic

- m_Texture의 m_PathID가 17이다.

- m_ConvertCase가 -2이다.

- m_CharacterRects에 아무런 데이터도 들어있지 않다.

- m_KerningValues에 데이터가 많이 들어있다. (59항목)

- m_FontData에 데이터가 아주 많이 들어있다. (4,691,820 항목)

 

 

Unicode

- m_Texture의 m_PathID가 13이다.

- m_ConvertCase가 -1이다.

- m_CharacterRects에 데이터가 아주 많이 들어있다. (17,634 항목)

- m_KerningValues에 데이터가 많이 들어있다. (59항목)

- m_FontData에 아무런 데이터도 들어있지 않다.

* 아직 UABEA/UnityEX 수정 전이므로, UnityEX용 폰트를 덤프떴다. Unicode와 완전히 동일하다.

 

 

Ascii 시리즈

- m_Texture의 m_PathID가 AsciiDefault:11, AsciiUpper:15, AsciiLower:18, Custom:12이다.

- m_ConvertCase가 AsciiDefault:0, AsciiUpper:1, AsciiLower:2, Custom:3이다.

- m_CharacterRects에 각각 95, 69, 69, 14개 항목이 들어있다.

* Custom에 "안녕하세요테스트123ABC" 총 14개 글자를 넣고 빌드했으며, AsciiUpper와 AsciiLower의 항목 수가 같고, 데이터 형식이 아래와 같은 걸 보니 글자의 좌표라고 추측할 수 있겠다.

   [0]
    0 CharacterInfo data
     0 unsigned int index = 32
     0 Rectf uv
      0 float x = 0
      0 float y = 0.015625
      0 float width = 0.015625
      0 float height = -0.015625
     0 Rectf vert
      0 float x = -1
      0 float y = 1
      0 float width = 2
      0 float height = -2
     0 float advance = 4
     1 bool flipped = false

- m_KerningValues는 AsciiDefault 및 AsciiUpper에만 있고, AsciiLower 및 Custom에는 없다.

- m_FontData는 넷 다 들어있지 않다.

 

 

----

현재까지 정리:

  Dynamic Unicode Ascii시리즈
m_Texture 17 13 11, 16, 18, 12
m_ConvertCase -2 -1 0, 1, 2, 3
m_CharacterRects X O O
m_KerningValues O O 혼재
m_FontData O X X

---

 

 

이제 UnityEX 및 UABEA가 하는 짓에 대해 알아보자.

 

좌측이 수정 후 Dump뜬 파일이다.

제일 먼저 눈에 띄는 부분이, m_FontData에 아까 봤던 값인 "4,691,820 항목"이 들어왔다는 것.

   [10]
    0 SInt8 data = 0
   [11]
    0 SInt8 data = 64
   [12]
    0 SInt8 data = 79

m_FontData의 데이터 형식도 마치 바이너리 데이터의 느낌...

TTF폰트의 바이너리 데이터를 그대로 때려박았다.

또한, m_ConvertCase가 Dynamic에서 사용되었던 -2로 바뀌었다.

 

 

이건 UABEA 플러그인을 통해 TTF폰트를 import시킨 경우이다.

마찬가지로 왼쪽이 수정 후 덤프이다.

이것도 마찬가지로 m_FontData에 바이너리 데이터가 그대로 박혀있지만

UnityEX와 다른 점은 m_ConvertCase가 변경되지 않고 그대로 -1이라는 것이다.

이걸 통해 UABEA Plugins의 ttf import기능은 m_FontData에 바이너리 데이터만 갖다박고, m_ConvertCase를 건들지 않아서 .ufnt 폰트 수정 시 정상적으로 작동되지 않았다는 것을 알 수 있다.

또한, UABEA로 .ufnt를 수정할 시 다시 추출해서 m_ConvertCase만 다시 수정해주면 정상적용이 가능하다는 것을 알 수 있다.

 

 

근데, 앞에서 확인했을 때

왜 Dynamic폰트가 아닌 다른 폰트들은 다 크기가 작았을까?

이건 텍스쳐 포인터를 따라가보면 알 수 있다.

 

다이나믹 폰트가 가리키고 있는 텍스쳐는 export되지 않는다.

유효하지 않단 소리

 

Unicode는 엄청난 크기의 텍스쳐와 문자들이 있다.

 

Ascii 종류 및 Custom은 예상대로 몇 글자 들어있지 않다.

 

 

 

---

 

비교분석을 통한 정리

- m_Texture의 PathID를 통해 텍스쳐를 직접 확인해봤을 때, Dynamic을 제외하곤 모두 유효한 글자 아틀라스였음.

- m_ConvertCase는 Dynamic/Unicode/Ascii/Custom 등에 대한 케이스 값이었으며, 이를 통해 폰트가 어떤 데이터를 사용할지 결정

- m_CharacterRects의 경우 Dynamic에만 들어있지 않는 것 및 데이터 형식을 보니 텍스쳐에 있는 글자 좌표임을 알 수 있음.

- m_KerningValues의 경우 혼재되어있는 모습, Dynamic과 비Dynamic으로 나눠지지 않는 걸 봤을 때 두개를 구분짓는 요소는 아님.

- m_FontData는 폰트의 바이너리 데이터.

 

- UnityEX를 통한 폰트 추출 시 .ufnt파일의 용량이 적은 이유는 Dynamic 이외의 방식은 모두 텍스쳐 + 글자 좌표를 사용하기 때문( m_Texture + m_CharacterInfo ). 텍스쳐가 따로 빠지고, 폰트 바이너리 데이터가 없기에 용량이 적음.

- UABEA의 Plugin을 통한 ttf import 기능 이용 시, .ufnt 폰트가 안바꿔지는 이유는 m_FontData에 폰트 바이너리 데이터만 넣어놓고, m_ConvertCase는 변경하지 않기 때문. m_ConvertCase는 그대로 -1이고, -1은 Unicode 모드이며, 이는 텍스쳐+ m_CharacterInfo를 사용하니 m_FontData를 넣든 말든 기존 폰트에서 바뀌지 않게 됨.

- 그러므로, UABEA를 통해 폰트 교체를 할 시 Plugins-import ttf를 통해 m_FontData에 폰트 바이너리 데이터를 집어넣고, 저장한 파일을 다시 추출해서 m_ConvertCase를 "Dynamic"모드인 -2로 바꿔줘야 원하는 폰트로 출력됨.