Unity Term Book
애니메이션 & UI

TextMesh Pro

TextMesh Pro는 Unity의 고급 텍스트 패키지로, SDF로 어떤 크기에서도 선명한 글자를 그립니다. 리치 텍스트 태그·Font Asset·Material Preset과 월드/UI 텍스트 효과, TMP_Text 활용법을 다루는 실전 가이드입니다. 도식과 시뮬레이터로 익힙니다.

상상해 보세요...

옛 Text 컴포넌트는 비트맵 폰트——글자가 이미지라 확대하면 흐려집니다. TextMesh Pro는 SDF(Signed Distance Field)——벡터처럼 각 문자가 수학 함수라 어떤 크기에서도 선명합니다. Rich text tags는 HTML처럼: 문자열에 color=red를 쓰면 그 구간이 빨개지고, 추가 Text 컴포넌트가 필요 없습니다.

개념 자세히

SDF Rendering: TextMesh Pro는 폰트에서 SDF texture를 만듭니다——각 픽셀이 가장 가까운 글리프 가장자리까지의 거리를 저장합니다. 렌더 시 셰이더가 어떤 스케일에서도 선명한 외곽선을 재구성합니다. 한 아틀라스로 8px부터 200px까지 재빌드 없이 표시할 수 있습니다.

Font Asset이 핵심 TMP 에셋입니다——SDF 텍스처와 메타데이터(간격, 커닝, 글리프). 생성: Window → TextMeshPro → Font Asset Creator. 소스 폰트 (.ttf/.otf), 문자 집합(ASCII, Unicode 범위), 아틀라스 크기를 고릅니다. Dynamic Atlas(2021+)로 필요 시 글리프를 추가——CJK에 적합합니다.

Rich Text Tags는 인라인 마크업입니다: <b>, <i>, <color=#ff0000>, <size=24>, <sprite index=0>, <gradient>, <link=“url”>… 한 문자열이 풍부한 서식을 담을 수 있습니다——대화, 스킬 툴팁, 데미지 숫자.

TMP에는 두 컴포넌트가 있습니다: TMP_Text (추상 베이스)와 TextMeshProUGUI (Canvas UI), TextMeshPro (World Space/3D). 항상 TMP_Text 를 참조하면 같은 코드가 둘 다에서 동작합니다.

Rich Text 태그 참고

Tag예시결과
<b>, <i><b>Bold</b> <i>Italic</i>Bold Italic
<color><color=red>danger</color>danger
<color=#hex><color=#f97316>fire</color>fire
<size><size=20>large</size>large
<sprite><sprite="icons" name="coin">🪙 (아틀라스의 sprite)
<link><link="item_001">Sword</link>Sword
<alpha><alpha=#88>ghost</alpha>ghost
<mark><mark=#ffff00aa>highlight</mark>highlight

실습 단계

1

TMP Essential Resources 임포트

Window → TextMeshPro → Import TMP Essential Resources. TMP 동작에 필요합니다(폰트, 셰이더, 설정).

2

커스텀 폰트에서 Font Asset 만들기

Window → TMP → Font Asset Creator → .ttf 선택, Atlas Resolution 512×512 이상, Generate → Save.

3

TMP Text 컴포넌트 추가

Canvas용 UI → Text - TextMeshPro. World Space용 Add Component → TextMeshPro. Font Asset을 할당합니다.

4

Inspector에서 리치 텍스트 사용

"Enable Rich Text"를 켠 채로(기본값). Text 필드에 태그를 직접 입력합니다.

5

한국어/CJK 문자 추가

Font Asset Creator → Character Set → Custom Range → Unicode 범위 입력. 또는 Dynamic Atlas Mode 사용.

인터랙티브 시뮬레이터

리치 텍스트 태그를 입력해 미리보기——Unity Inspector의 TMP 필드와 비슷합니다.

Preview

코드 예제

기본

스크립트에서 TMP_Text 사용——런타임 텍스트, 리치 텍스트, 색상.

using UnityEngine;
using TMPro; // TextMesh Pro namespace

public class TMPController : MonoBehaviour
{
  // TMP_Text works for both UI and World Space
  [SerializeField] TMP_Text titleText;
  [SerializeField] TMP_Text damageText;

  public void ShowDamage(int amount, bool isCrit)
  {
      if (isCrit)
      {
          // Critical hit: gold, larger type
          damageText.text = $"<color=#fbbf24><size=1.5em><b>CRIT {amount}</b></size></color>";
      }
      else
      {
          damageText.text = $"<color=red>-{amount}</color>";
      }
  }

  public void SetTitle(string name, int level)
  {
      // TMP_Text.SetText() can be cheaper than assigning .text
      titleText.text = $"{name} <size=0.7em><color=#64748b>Lv.{level}</color></size>";
  }

  // Vertex color without tags
  public void SetColor(Color c)
  {
      titleText.color = c;
  }
}

코드 예제

고급

타자기 효과——코루틴으로 문자를 하나씩 공개, 태그 포함.

using UnityEngine;
using System.Collections;
using TMPro;

public class TypewriterEffect : MonoBehaviour
{
  [SerializeField] TMP_Text dialogText;
  [SerializeField] float charDelay = 0.04f;

  Coroutine current;

  public void ShowText(string text)
  {
      if (current != null) StopCoroutine(current);
      current = StartCoroutine(TypeRoutine(text));
  }

  IEnumerator TypeRoutine(string text)
  {
      dialogText.text = text;
      dialogText.ForceMeshUpdate(); // Rebuild the mesh immediately

      TMP_TextInfo info = dialogText.textInfo;
      int total = info.characterCount;

      // Hide every character via alpha
      for (int i = 0; i < total; i++)
      {
          SetCharAlpha(i, 0);
      }

      // Reveal one by one
      for (int i = 0; i < total; i++)
      {
          SetCharAlpha(i, 255);
          dialogText.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
          yield return new WaitForSeconds(charDelay);
      }
  }

  void SetCharAlpha(int charIdx, byte alpha)
  {
      TMP_TextInfo info = dialogText.textInfo;
      if (charIdx >= info.characterCount) return;
      int matIdx = info.characterInfo[charIdx].materialReferenceIndex;
      int vertIdx = info.characterInfo[charIdx].vertexIndex;
      Color32[] colors = info.meshInfo[matIdx].colors32;
      for (int k = 0; k < 4; k++) colors[vertIdx + k].a = alpha;
  }
}

📌 빠른 정리

  • SDF: 한 아틀라스로 어떤 크기에서도 선명한 텍스트
  • TextMeshProUGUI: Canvas UI; TextMeshPro: World/3D
  • TMP_Text(베이스)를 참조해 한 스크립트로 둘 다 커버
  • textInfo가 당장 필요하면 ForceMeshUpdate()
  • 큰 문자 집합(한국어, CJK)은 Dynamic Atlas Mode

⚠️ 흔한 실수

  • ❌ 문자가 □(두부)로 표시됨

    Font Asset에 해당 글리프가 없음

    ✅ 해당 언어를 커버하는 Unicode 범위로 Font Asset을 재생성

  • ❌ 리치 텍스트 태그가 아무 효과 없음

    TMP 컴포넌트에서 Enable Rich Text가 꺼짐

    ✅ Inspector → Extra Settings → Enable Rich Text = ON