Localization & Semantic Anchors
Texturge provides built-in localization support, solving a core challenge in cross-language text animation — how to position animation effects within translated text.
The Problem
When the text “Hello World” is translated to Chinese “你好世界”:
- The character count changes from 11 to 4
- Every character’s position shifts entirely
- The per-character animation originally targeting “World” cannot simply shift by character index
Texturge solves this with Semantic Anchors and the Localization Subsystem.
ULocalizationSubsystem
ULocalizationSubsystem is a UGameInstanceSubsystem that initializes automatically on game startup.
Core Features
| Feature | Description |
|---|---|
| Language switching | SetLanguage(CultureCode) switches the current language, triggering StringTable reload and anchor relocation |
| Anchor relocation | RelocateAnchors() locates each semantic anchor’s new position in the target language text |
| Cache management | AnchorCache caches anchor query results; ClearCache() forces recomputation |
| Event broadcasting | OnLanguageChanged multicast delegate notifies all listeners of language changes |
Lifecycle
GameInstance startup
│
▼
Initialize()
├── Scan StringTable assets
└── Bind FInternationalization::OnCultureChanged
│
▼ (on language switch)
OnCultureChanged()
├── ClearCache()
└── Broadcast OnLanguageChanged
API
// Set language
Subsystem->SetLanguage("zh-CN");
// Relocate anchors
TMap<FName, int32> NewPositions = Subsystem->RelocateAnchors(
Anchors, // Semantic anchor array
SourceText, // Source language text
TargetText // Target language text
);
// Clear cache
Subsystem->ClearCache();
Semantic Anchor
struct FSemanticAnchor
{
FName AnchorId; // Unique anchor identifier
FString ContextualSnippet; // Context snippet (for location)
int32 SourceOffset; // Offset in source text
};
How It Works
-
Definition phase: In the source language text, define anchors at key positions. Each anchor contains a
ContextualSnippet(a context fragment, typically a few words around the anchor) and aSourceOffset(the character index of that position in the source text). -
Relocation phase: After a language switch,
RelocateAnchors()for each anchor:- Attempts an exact match of the
ContextualSnippetin the target text - If exact match fails, uses Longest Common Substring (LCS) algorithm for approximate matching
- Calculates a match confidence (
CalculateConfidence()) - Returns the new offset in the target text
- Attempts an exact match of the
-
Application phase: The animation system uses the new offsets to adjust the scope of animation effects.
Matching Strategies
| Strategy | Description |
|---|---|
| Exact match | Directly find ContextualSnippet as a substring in the target text |
| LCS approximate | When exact match fails, compute longest common substring between source snippet and target text positions, selecting the longest match |
Match Confidence
Confidence = MatchLength / SnippetLength
Confidence ranges from 0.0 to 1.0. Callers can set a threshold to decide whether to accept approximate matches.
Widget Integration
Both UAnimatedTextBlock and UAnimatedRichTextBlock listen for the OnLanguageChanged event. On language switch they automatically:
- Obtain the new language version of the text (via StringTable reload mechanism)
- Re-execute the animation pipeline (
SetPlainText/SetRichText→ExecutePipeline) - If anchors are configured, use
RelocateAnchors()to position animation effects at new locations
StringTable Integration
ScanStringTableAssets() scans all UStringTable assets in the project, filtering for those registered under the specified namespace prefix. These tables are used to automatically provide translated text on language switch.
Localization Data
Texturge’s built-in text is already localized. Localization files are at Plugins/Texturge/Content/Localization/Texturge/:
| Language | Culture Code | File |
|---|---|---|
| Simplified Chinese (native) | zh-Hans | zh-Hans/Texturge.locres |
| English | en | en/Texturge.locres |