Unused Key Detection Pro
Unused Key Detection scans your project to find localization keys that exist in string tables but are not referenced anywhere in your codebase.
Benefits
| Benefit | Description |
|---|---|
| Cost Savings | Avoid translating strings that are no longer used |
| Cleaner Tables | Remove dead entries to improve maintainability |
| Bug Detection | Identify orphaned keys that may indicate missing features |
| Project Health | Keep localization data in sync with actual usage |
Running the Scanner
From String Table Browser
- Open Tools → KitStack → Lexis → String Table Browser
- Click the Validation tab
- Click Scan Unused Keys
- Wait for the scan to complete (progress bar shows status)
- Review the results
From Menu (Quick Access)
Tools → KitStack → Lexis → Scan Unused Keys
Scan Results
The scanner reports:
- Unused Keys (Warning): Keys defined in tables but not found in code or assets
- Dynamic Key Warnings (Info): Locations where dynamic key lookup is detected
Example Results:
[Warning] Unused key 'ui.old_button' in table 'UI': Old button text
[Warning] Unused key 'menu.deprecated' in table 'Menu': (no default value)
[Info] Dynamic key usage detected at PlayerUI.cs:42. Some keys may not be detected.What Gets Scanned
| Source | Patterns Detected |
|---|---|
| C# Code | Localization.Get("key"), new LocalizedString("key"), .Key = "key" |
| Scenes | Serialized LocalizedString fields in components |
| Prefabs | Serialized LocalizedString fields in prefabs |
| ScriptableObjects | Serialized LocalizedString fields in .asset files |
Detection Patterns in Code
csharp
// Direct lookups
Localization.Get("ui.title");
Localization.Get("MyTable", "my.key");
// LocalizedString construction
new LocalizedString("button.text");
new LocalizedString("UI", "dialog.title");
// Property assignment
localizedString.Key = "assigned.key";
// Asset lookups
LocalizedAsset<Sprite>.Load("icons.menu");Dynamic Key Detection
When the scanner detects dynamic key usage, it reports a warning because these keys cannot be statically analyzed:
csharp
// This triggers a dynamic key warning
string keyName = "ui." + buttonType;
Localization.Get(keyName); // Dynamic key detectedHandling Dynamic Keys
- Use exclusion patterns for dynamic key prefixes
- Verify dynamic keys manually
- Consider refactoring to use static keys where possible
Exclusion Patterns
Exclude keys from unused detection using regex patterns:
^test_.* // Exclude keys starting with "test_"
^debug_.* // Exclude debug keys
.*_placeholder // Exclude placeholder keys
^system\..* // Exclude system keysConfiguration
Configure detection settings programmatically:
csharp
using Lexis.Editor.Validation;
var detector = new UnusedKeyDetector();
var settings = new UnusedKeyDetectionSettings
{
ScanCode = true,
ScanScenes = true,
ScanPrefabs = true,
ScanScriptableObjects = true,
ExclusionPatterns = new[] { "^test_.*", "^debug_.*" }
};
var report = detector.ScanProject(localizationSettings, settings);
// Process results
foreach (var unused in report.UnusedKeys)
{
Debug.Log($"Unused: {unused.TableId}/{unused.Key}");
}
// Check statistics
Debug.Log($"Total Keys: {report.TotalKeysScanned}");
Debug.Log($"Unused: {report.UnusedKeyCount}");
Debug.Log($"Files Scanned: {report.FilesScanned}");
Debug.Log($"Duration: {report.ScanDuration.TotalSeconds:F1}s");CI/CD Integration
Run unused key detection from the command line:
Basic Usage
bash
Unity -batchmode -projectPath /path/to/project \
-executeMethod Lexis.Editor.Validation.UnusedKeyDetectorCI.RunFromCommandLine \
-quitFail Build on Unused Keys
bash
Unity -batchmode -projectPath /path/to/project \
-executeMethod Lexis.Editor.Validation.UnusedKeyDetectorCI.RunFromCommandLine \
-failOnUnused \
-quitWith Options
bash
Unity -batchmode -projectPath /path/to/project \
-executeMethod Lexis.Editor.Validation.UnusedKeyDetectorCI.RunFromCommandLine \
-settingsPath "Assets/Settings/LocalizationSettings.asset" \
-outputFile "reports/unused-keys.json" \
-excludePattern "^test_.*" \
-excludePattern "^debug_.*" \
-quitCommand Line Arguments
| Argument | Description |
|---|---|
-settingsPath "path" | Path to LocalizationSettings asset |
-failOnUnused | Exit with code 1 if unused keys are found |
-outputFile "path" | Write JSON report to specified file |
-excludePattern "pat" | Regex pattern to exclude (can be repeated) |
-skipScenes | Skip scene file scanning |
-skipPrefabs | Skip prefab file scanning |
-skipScriptableObjects | Skip ScriptableObject scanning |
-skipCode | Skip C# code scanning |
Exit Codes
0: Success (no unused keys, or unused keys found but-failOnUnusednot set)1: Unused keys found (when-failOnUnusedis set)2: Error (settings not found, exception, etc.)
Performance
| Project Size | Typical Scan Time |
|---|---|
| Small (<100 files) | < 5 seconds |
| Medium (100-1000 files) | 5-30 seconds |
| Large (1000+ files) | 30+ seconds |
For large projects:
- Run scans during development, not on every build
- Use
CodeSearchPathsto limit scanning to specific folders - Disable
ScanScriptableObjectsif not using LocalizedString in SOs
Best Practices
- Run Regularly: Scan for unused keys after major refactoring
- Use Exclusion Patterns: Set up patterns for known dynamic key prefixes
- Review Before Deleting: Verify keys aren't used in external systems
- Handle Dynamic Keys: Document dynamic key patterns in comments
- CI Integration: Add unused key detection to your build pipeline
