TextMeshPro (TMPro) expert for Unity text rendering with advanced typography, performance optimization, and professional text effects. Masters font asset creation, dynamic fonts, rich text formatting, material presets, and text mesh optimization. Use PROACTIVELY for text rendering, font management, localization text, UI text performance, or text effects implementation.
Expertly optimizes Unity text rendering using TextMeshPro's SDF technology for resolution-independent typography. Triggers when implementing UI text, font assets, or performance-critical text systems.
/plugin marketplace add creator-hian/claude-code-plugins/plugin install unity-plugin@creator-hian-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/advanced-patterns.mdreferences/fundamentals.mdreferences/performance-optimization.mdTextMeshPro (TMPro) is Unity's advanced text rendering solution using Signed Distance Field (SDF) technology for resolution-independent, high-quality text with minimal performance overhead.
Foundation Required: unity-csharp-fundamentals (TryGetComponent, FindAnyObjectByType), unity-ui (UI systems, Canvas, UGUI)
Core Topics:
using TMPro;
using UnityEngine;
public class TextController : MonoBehaviour
{
[SerializeField] private TMP_Text mDisplayText;
void Start()
{
mDisplayText.text = "Hello, World!";
mDisplayText.fontSize = 36;
mDisplayText.color = Color.white;
}
}
// TMP_Text - Base class, use for serialization (works with both)
[SerializeField] private TMP_Text mText;
// TextMeshProUGUI - Canvas UI text (most common)
[SerializeField] private TextMeshProUGUI mUiText;
// TextMeshPro - 3D world space text (MeshRenderer)
[SerializeField] private TextMeshPro mWorldText;
// Basic formatting
text.text = "<b>Bold</b> and <i>Italic</i>";
text.text = "<size=48>Large</size> and <size=24>Small</size>";
text.text = "<color=#FF0000>Red</color> text";
// Advanced formatting
text.text = "<mark=#FFFF00AA>Highlighted</mark>";
text.text = "H<sub>2</sub>O and E=mc<sup>2</sup>";
text.text = "<s>Strikethrough</s> and <u>Underline</u>";
// Sprite embedding
text.text = "Score: 100 <sprite=0>";
| Scenario | Component | Reason |
|---|---|---|
| UI Canvas text | TextMeshProUGUI | Canvas integration, auto-batching |
| 3D world labels | TextMeshPro | MeshRenderer, world-space |
| Serialized reference | TMP_Text | Works with both types |
| Input field | TMP_InputField | Built-in input handling |
| Dropdown | TMP_Dropdown | Built-in dropdown UI |
Static Font Asset:
- Pre-generated character set
- Best performance (no runtime generation)
- Use for: Known character sets, optimized builds
Dynamic Font Asset:
- Runtime character generation
- Flexible but slower initial render
- Use for: Localization, user input, unknown characters
Font Asset Creator (Window > TextMeshPro > Font Asset Creator)
Sampling Point Size: Use highest size that fits atlas (better quality)
Padding: 5-9 for normal use, higher for effects (outline, glow)
// BAD: Frequent text changes trigger mesh rebuild
void Update()
{
scoreText.text = $"Score: {score}"; // Rebuilds every frame
}
// GOOD: Update only when value changes
private int mLastScore = -1;
void Update()
{
if (score != mLastScore)
{
mLastScore = score;
scoreText.text = $"Score: {score}";
}
}
// BETTER: Use SetText for formatted updates (less allocation)
void UpdateScore(int score)
{
scoreText.SetText("Score: {0}", score);
}
// Use StringBuilder for complex text construction
private readonly StringBuilder mSb = new StringBuilder(256);
void BuildComplexText()
{
mSb.Clear();
mSb.Append("Player: ");
mSb.Append(playerName);
mSb.Append(" | Score: ");
mSb.Append(score);
displayText.SetText(mSb);
}
// Prefer SetText with parameters over string interpolation
text.SetText("{0}/{1}", currentHP, maxHP); // Less GC
// Instead of
text.text = $"{currentHP}/{maxHP}"; // More GC
// Apply material preset at runtime
[SerializeField] private Material mHighlightMaterial;
[SerializeField] private Material mNormalMaterial;
void Highlight(bool active)
{
mText.fontMaterial = active ? mHighlightMaterial : mNormalMaterial;
}
// Modify material properties
mText.fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0.2f);
mText.fontMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
Core TextMeshPro concepts:
Optimization techniques:
Advanced usage patterns:
// AVOID: Creating new materials per text instance
text.fontMaterial = new Material(text.fontMaterial); // Memory leak risk
// AVOID: Updating text in Update() without change check
void Update() { text.text = score.ToString(); } // Constant rebuild
// AVOID: Excessive rich text nesting
text.text = "<b><i><color=#FF0000><size=48>...</size></color></i></b>";
// AVOID: Dynamic fonts for static content
// Use pre-generated static font assets instead
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.