com.xmobitea.changx.mini-localization 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +101 -61
- package/AI_API_REFERENCE.md +281 -0
- package/AI_API_REFERENCE.md.meta +7 -0
- package/AI_BEHAVIOR.md +269 -0
- package/AI_BEHAVIOR.md.meta +7 -0
- package/AI_SETUP.md +26 -0
- package/AI_SETUP.md.meta +7 -0
- package/AI_SETUP_LOCALIZATION_MANAGER.md +91 -0
- package/AI_SETUP_LOCALIZATION_MANAGER.md.meta +7 -0
- package/AI_SETUP_LOCALIZATION_SETTINGS.md +191 -0
- package/AI_SETUP_LOCALIZATION_SETTINGS.md.meta +7 -0
- package/AI_USAGE.md +138 -56
- package/CHANGELOG.md +28 -15
- package/Editor/LocalizationComponentWindowsEditor.cs +27 -30
- package/Editor/LocalizationKeyDrawer.cs +121 -121
- package/Editor/LocalizationManagerEditor.cs +265 -232
- package/Editor/LocalizationSettingsEditor.cs +14 -14
- package/README.md +91 -528
- package/Runtime/LocalizationComponent.cs +2 -11
- package/Runtime/LocalizationLanguageItem.cs +10 -10
- package/Runtime/LocalizationManager.cs +37 -37
- package/Runtime/LocalizationSettings.cs +22 -22
- package/Runtime/TMP_LocalizationComponent.cs +1 -10
- package/Samples~/Example/English.xml +10 -0
- package/Samples~/Example/English.xml.meta +7 -0
- package/Samples~/Example/LocalizationSample.csv +6 -0
- package/Samples~/Example/LocalizationSample.csv.meta +7 -0
- package/Samples~/Example/README.md +47 -0
- package/Samples~/Example/README.md.meta +7 -0
- package/Samples~/Example/Vietnamese.xml +10 -0
- package/Samples~/Example/Vietnamese.xml.meta +7 -0
- package/Samples~/Example.meta +8 -0
- package/package.json +21 -10
package/AGENTS.md
CHANGED
|
@@ -1,67 +1,107 @@
|
|
|
1
|
-
# XmobiTea Localization
|
|
1
|
+
# XmobiTea Localization Agent Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Scope: everything inside `Assets/XmobiTea Localization`.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Need-Based Routing
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Choose by current need. Open the smallest file that answers it.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- `FetchType` controls the editor fetch source: `None`, `FromGoogleSheets`, or `FromCsv`.
|
|
20
|
-
- CSV fetch reads a `TextAsset` assigned in settings, parses it with `CsvParser`, and writes XML files to disk. It does not alter the runtime dictionary directly.
|
|
21
|
-
|
|
22
|
-
## Required Mental Model
|
|
23
|
-
|
|
24
|
-
Treat this package as:
|
|
25
|
-
|
|
26
|
-
- a scene-managed localization system,
|
|
27
|
-
- XML-driven translation storage at runtime,
|
|
28
|
-
- CSV-driven or Google-Sheets-driven fetch workflow in the editor (CSV is converted to XML before being used at runtime),
|
|
29
|
-
- key-based lookup plus UI refresh events,
|
|
30
|
-
- editor-assisted setup and code generation.
|
|
31
|
-
|
|
32
|
-
Do not treat this package as:
|
|
33
|
-
|
|
34
|
-
- an auto-configuring localization framework,
|
|
35
|
-
- a strongly typed localization database,
|
|
36
|
-
- a schema-validated content pipeline,
|
|
37
|
-
- a one-shot synchronous load system when addressable or online sources are enabled.
|
|
38
|
-
|
|
39
|
-
## Correct Usage Pattern
|
|
9
|
+
| Need | Use |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| Choose localization API or generate common runtime code | `AI_USAGE.md` |
|
|
12
|
+
| Setup router | `AI_SETUP.md` |
|
|
13
|
+
| Scene object, singleton timing, bootstrap, persistent manager | `AI_SETUP_LOCALIZATION_MANAGER.md` |
|
|
14
|
+
| Settings asset, language items, XML, CSV/Google import, constants | `AI_SETUP_LOCALIZATION_SETTINGS.md` |
|
|
15
|
+
| Exact signatures, return values, serialized fields, XML shape, editor menus | `AI_API_REFERENCE.md` |
|
|
16
|
+
| Lifecycle, source precedence, async refreshes, fetch edge cases | `AI_BEHAVIOR.md` |
|
|
17
|
+
| Package summary for humans | `README.md` |
|
|
18
|
+
| Missing or conflicting doc detail | source code |
|
|
40
19
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
1. Ensure `LocalizationManager` exists in scene.
|
|
44
|
-
2. Ensure `LocalizationSettings` exists in `Resources`.
|
|
45
|
-
3. Configure one or more `LocalizationLanguageItem` entries.
|
|
46
|
-
4. Call `ChooseLanguage(...)` during bootstrap.
|
|
47
|
-
5. Bind UI through localization components or direct `GetText(...)` calls.
|
|
48
|
-
|
|
49
|
-
## Incorrect Assumptions
|
|
50
|
-
|
|
51
|
-
These assumptions are false:
|
|
52
|
-
|
|
53
|
-
- translations are active immediately just because the manager exists.
|
|
54
|
-
- generated constants always exist without editor generation.
|
|
55
|
-
- online localization merges into local localization without replacing it.
|
|
56
|
-
- `GetText(...)` returns null when a key is missing.
|
|
57
|
-
|
|
58
|
-
## Operational Consequences
|
|
59
|
-
|
|
60
|
-
If an agent writes code against this package:
|
|
20
|
+
## Hard Rules
|
|
61
21
|
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
22
|
+
- `LocalizationManager` is a scene-hosted `Singleton<LocalizationManager>`.
|
|
23
|
+
- The package does not auto-create a missing manager.
|
|
24
|
+
- Static APIs require the singleton to initialize first.
|
|
25
|
+
- The conventional host object name is `LocalizationManager`, but runtime depends on the initialized component.
|
|
26
|
+
- Use `XmobiTea.MiniSingleton.DontDestroy` only when later scenes need the same host.
|
|
27
|
+
- Runtime settings lookup key is `XmobiTea LocalizationSettings`; `Open Settings` creates the asset at `Assets/Resources/XmobiTea LocalizationSettings.asset`.
|
|
28
|
+
- `LocalizationSettings.ResourcesPath` is exactly `XmobiTea LocalizationSettings`.
|
|
29
|
+
- `ChooseLanguage(...)` populates the active dictionary.
|
|
30
|
+
- `GetText(...)` falls back to the original key.
|
|
31
|
+
- `LocalizationComponent` targets `UnityEngine.UI.Text`.
|
|
32
|
+
- `TMP_LocalizationComponent` targets `TMP_Text` and exists only with TextMesh Pro support.
|
|
33
|
+
- Fixed labels, titles, descriptions, tabs, and button captions should use localization components.
|
|
34
|
+
- `LocalizationManager.OnUpdateText` is a public static `Action`; subscribe with `+=`/`-=` and never overwrite it.
|
|
35
|
+
- Local XML loads synchronously first.
|
|
36
|
+
- Addressables XML can add/overwrite keys after async load completes.
|
|
37
|
+
- Successful online XML clears and replaces the active dictionary.
|
|
38
|
+
- If one language configures both Addressables XML and online XML, both async loads run and the callback that finishes later mutates the dictionary last.
|
|
39
|
+
- `OnUpdateText` can fire more than once for one `ChooseLanguage(...)` call.
|
|
40
|
+
- Runtime never reads CSV or Google Sheets.
|
|
41
|
+
- `fetchType` is editor-only: `None`, `FromGoogleSheets`, `FromCsv`.
|
|
42
|
+
- `worksheetKey` is required only when either fetch type is `FromGoogleSheets`.
|
|
43
|
+
- CSV rows must include `Key` plus one cell per configured language.
|
|
44
|
+
- Generated constants come from editor tooling, not runtime discovery.
|
|
45
|
+
- Generated `LocalizationConstantId` members are `public static readonly string`.
|
|
46
|
+
- The generator reads keys from the first configured language item's local XML.
|
|
47
|
+
|
|
48
|
+
## Do Not Assume
|
|
49
|
+
|
|
50
|
+
- `LocalizationManager` or `LocalizationSettings` will be created at runtime.
|
|
51
|
+
- Translations are active before `ChooseLanguage(...)`.
|
|
52
|
+
- A missing key returns `null`.
|
|
53
|
+
- One language switch means exactly one `OnUpdateText` call.
|
|
54
|
+
- Online XML merges with local XML.
|
|
55
|
+
- CSV or Google Sheets are runtime data sources.
|
|
56
|
+
- Generated constants are type-safe or auto-updated.
|
|
57
|
+
- Keys missing from the first local XML will generate constants.
|
|
58
|
+
- Nonexistent APIs exist: `SetLanguage`, `CurrentLanguage`, `GetLocalizedText`, `ReloadLanguage`, `FormatText`, `HasKey`.
|
|
59
|
+
|
|
60
|
+
## Code Generation Guidance
|
|
61
|
+
|
|
62
|
+
- Use `using XmobiTea.MiniLocalization;`.
|
|
63
|
+
- Add `using XmobiTea.MiniLocalization.Core;` only when declaring `LocalizationLanguageItem`.
|
|
64
|
+
- Prefer generated `LocalizationConstantId` values when the generated file exists and is current.
|
|
65
|
+
- Use raw key strings in fresh setups until constants are generated.
|
|
66
|
+
- Put language selection in `Start()` or later unless execution order guarantees manager initialization.
|
|
67
|
+
- Generate scene setup instructions instead of constructing a manager from code.
|
|
68
|
+
- Use `LocalizationComponent` / `TMP_LocalizationComponent` for fixed UI text.
|
|
69
|
+
- Generate custom text refresh code only for dynamic/composed text, non-UI state, or custom rendering.
|
|
70
|
+
- Custom listeners must unsubscribe and must tolerate repeated refreshes.
|
|
71
|
+
- Treat fallback-to-key display as normal runtime behavior.
|
|
72
|
+
- Before using constants, verify the first configured language XML contains the complete key set.
|
|
73
|
+
- Use `Samples~/Example` as the known-good CSV/XML shape.
|
|
74
|
+
|
|
75
|
+
## Setup Contract
|
|
76
|
+
|
|
77
|
+
When generated code depends on localization, require:
|
|
78
|
+
|
|
79
|
+
1. A loaded scene contains one active `LocalizationManager`.
|
|
80
|
+
2. Static APIs run after `LocalizationManager.Awake()`.
|
|
81
|
+
3. A `LocalizationSettings` asset loadable as `Resources.Load<LocalizationSettings>("XmobiTea LocalizationSettings")` exists.
|
|
82
|
+
4. `localizationLanguageItems` contains the requested language.
|
|
83
|
+
5. Runtime language items have local XML unless deliberately online/addressable-only.
|
|
84
|
+
6. Bootstrap calls `ChooseLanguage(...)`.
|
|
85
|
+
7. Fixed UI text uses localization components.
|
|
86
|
+
8. Constants are regenerated after key changes.
|
|
87
|
+
9. Fetch workflows verify assigned CSV assets, local XML targets, Google `worksheetKey`, and complete language columns.
|
|
88
|
+
|
|
89
|
+
## Maintenance Checklist
|
|
90
|
+
|
|
91
|
+
If changing resource paths, manager lifecycle, XML parsing, source precedence, generated constants, editor fetch behavior, component binding, or event semantics, update these together:
|
|
92
|
+
|
|
93
|
+
- `Runtime/LocalizationManager.cs`
|
|
94
|
+
- `Runtime/LocalizationSettings.cs`
|
|
95
|
+
- `Runtime/LocalizationLanguageItem.cs`
|
|
96
|
+
- `Runtime/LocalizationComponent.cs`
|
|
97
|
+
- `Runtime/TMP_LocalizationComponent.cs`
|
|
98
|
+
- `Editor/LocalizationManagerEditor.cs`
|
|
99
|
+
- `Editor/LocalizationSettingsEditor.cs`
|
|
100
|
+
- `Editor/LocalizationKeyDrawer.cs`
|
|
101
|
+
- `AI_USAGE.md`
|
|
102
|
+
- `AI_SETUP.md`
|
|
103
|
+
- `AI_SETUP_LOCALIZATION_MANAGER.md`
|
|
104
|
+
- `AI_SETUP_LOCALIZATION_SETTINGS.md`
|
|
105
|
+
- `AI_API_REFERENCE.md`
|
|
106
|
+
- `AI_BEHAVIOR.md`
|
|
107
|
+
- `README.md`
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# AI API Reference For XmobiTea Localization
|
|
2
|
+
|
|
3
|
+
Read this only when exact signatures, return values, serialized fields, XML shape, or editor menu names matter. Use `AI_SETUP_LOCALIZATION_MANAGER.md` for manager setup and `AI_SETUP_LOCALIZATION_SETTINGS.md` for settings/import preflight.
|
|
4
|
+
|
|
5
|
+
Required imports for runtime usage:
|
|
6
|
+
|
|
7
|
+
```csharp
|
|
8
|
+
using UnityEngine;
|
|
9
|
+
using XmobiTea.MiniLocalization;
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Additional import only when code declares `LocalizationLanguageItem` directly:
|
|
13
|
+
|
|
14
|
+
```csharp
|
|
15
|
+
using XmobiTea.MiniLocalization.Core;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## LocalizationManager API
|
|
19
|
+
|
|
20
|
+
| Signature | Returns | Use for | Missing manager |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
| `public static bool ChooseLanguage(SystemLanguage systemLanguage)` | `true` on accepted language, otherwise `false` | activate or switch language | logs error and returns `false` |
|
|
23
|
+
| `public static string GetText(string key)` | translated text or original `key` | direct string lookup | returns `key` |
|
|
24
|
+
| `public static LocalizationLanguageItem GetCurrentLanguage()` | active item or `null` | inspect selected language | logs error and returns `null` |
|
|
25
|
+
| `public static LocalizationLanguageItem[] GetAllLanguageItem()` | configured items or `null` | show language choices | logs error and returns `null` |
|
|
26
|
+
| `public static string GetTextWithoutBOM(TextAsset textAsset)` | text content | helper for XML `TextAsset` parsing | no manager needed; `textAsset` must be non-null |
|
|
27
|
+
| `public static Action OnUpdateText` | event field | refresh custom state after dictionary updates | no automatic guard |
|
|
28
|
+
|
|
29
|
+
`ChooseLanguage(...)` returns `false` when the requested `SystemLanguage` is not configured.
|
|
30
|
+
|
|
31
|
+
`GetAllLanguageItem()` reloads `LocalizationSettings` from `Resources`; it does not return a cached copy from the active language dictionary.
|
|
32
|
+
|
|
33
|
+
`OnUpdateText` is a public static `Action` field, not a C# `event`. Subscribe with `+=` and unsubscribe with `-=`. Do not assign it with `=` or set it to `null`.
|
|
34
|
+
|
|
35
|
+
## Component API
|
|
36
|
+
|
|
37
|
+
| Type | Target | Use for | Key field |
|
|
38
|
+
| --- | --- | --- | --- |
|
|
39
|
+
| `LocalizationComponentBase : MonoBehaviour` | abstract | shared event subscription and key storage | `[LocalizationKey] protected string _key` |
|
|
40
|
+
| `LocalizationComponent : LocalizationComponentBase` | `UnityEngine.UI.Text` | UGUI text binding | `key` property |
|
|
41
|
+
| `TMP_LocalizationComponent : LocalizationComponentBase` | `TMP_Text` | TextMesh Pro binding | `key` property |
|
|
42
|
+
|
|
43
|
+
`TMP_LocalizationComponent` is compiled only when `UNITY_USING_TMPRO` is defined by the package asmdef version define for `com.unity.textmeshpro`.
|
|
44
|
+
|
|
45
|
+
`LocalizationComponentBase` exposes:
|
|
46
|
+
|
|
47
|
+
```csharp
|
|
48
|
+
public string key { get; set; }
|
|
49
|
+
public virtual void OnUpdateText();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Lifecycle behavior:
|
|
53
|
+
|
|
54
|
+
- `OnEnable()` removes then adds `OnUpdateText` to `LocalizationManager.OnUpdateText`.
|
|
55
|
+
- `OnEnable()` immediately calls `OnUpdateText()`.
|
|
56
|
+
- `OnDisable()` unsubscribes.
|
|
57
|
+
|
|
58
|
+
`LocalizationComponent` auto-fills its target only in `OnValidate()` when the serialized target is empty and the component sits on the same object as `Text`. The same pattern applies to `TMP_LocalizationComponent`.
|
|
59
|
+
|
|
60
|
+
## LocalizationSettings API
|
|
61
|
+
|
|
62
|
+
```csharp
|
|
63
|
+
public enum FetchType
|
|
64
|
+
{
|
|
65
|
+
None = 0,
|
|
66
|
+
FromGoogleSheets = 1,
|
|
67
|
+
FromCsv = 2,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public class LocalizationSettings : ScriptableObject
|
|
71
|
+
{
|
|
72
|
+
public const string ResourcesPath = "XmobiTea LocalizationSettings";
|
|
73
|
+
public string worksheetKey { get; }
|
|
74
|
+
public LocalizationLanguageItem[] localizationLanguageItems { get; }
|
|
75
|
+
public FetchType fetchTypeLocalLocalization { get; }
|
|
76
|
+
public string sheetnameFetchLocalLocalization { get; }
|
|
77
|
+
public TextAsset csvFetchLocalLocalization { get; }
|
|
78
|
+
public FetchType fetchTypeOnlineLocalization { get; }
|
|
79
|
+
public string sheetnameFetchOnlineLocalization { get; }
|
|
80
|
+
public TextAsset csvFetchOnlineLocalization { get; }
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Serialized fields in the asset:
|
|
85
|
+
|
|
86
|
+
| Inspector field | Runtime property | Used by |
|
|
87
|
+
| --- | --- | --- |
|
|
88
|
+
| `_worksheetKey` | `worksheetKey` | editor Google Sheets fetch; required when either fetch type is `FromGoogleSheets` |
|
|
89
|
+
| `_localizationLanguageItems` | `localizationLanguageItems` | runtime language registry |
|
|
90
|
+
| `_fetchTypeLocalLocalization` | `fetchTypeLocalLocalization` | editor local import |
|
|
91
|
+
| `_sheetNameFetchLocalLocalization` | `sheetnameFetchLocalLocalization` | editor Google Sheets local import |
|
|
92
|
+
| `_csvFetchLocalLocalization` | `csvFetchLocalLocalization` | editor CSV local import |
|
|
93
|
+
| `_fetchTypeOnlineLocalization` | `fetchTypeOnlineLocalization` | editor online-file import |
|
|
94
|
+
| `_sheetNameFetchOnlineLocalization` | `sheetnameFetchOnlineLocalization` | editor Google Sheets online import |
|
|
95
|
+
| `_csvFetchOnlineLocalization` | `csvFetchOnlineLocalization` | editor CSV online import |
|
|
96
|
+
|
|
97
|
+
Default asset path created by `Open Settings`:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
Assets/Resources/XmobiTea LocalizationSettings.asset
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Runtime load:
|
|
104
|
+
|
|
105
|
+
```csharp
|
|
106
|
+
Resources.Load<LocalizationSettings>(LocalizationSettings.ResourcesPath)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## LocalizationSettings Inspector Setup
|
|
110
|
+
|
|
111
|
+
Use this checklist when generating setup instructions:
|
|
112
|
+
|
|
113
|
+
| Inspector field | Required when | Value rule |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| `Localization Language Length` | always | inspector-only size control that resizes `_localizationLanguageItems` |
|
|
116
|
+
| `systemLanguage` | always per language | Unity `SystemLanguage` value |
|
|
117
|
+
| `flagSpr` | optional | display icon only |
|
|
118
|
+
| `xml` | normal runtime local XML | assign an existing XML `TextAsset` asset |
|
|
119
|
+
| `xmlRef` | optional Addressables runtime XML | shown only when Addressables is installed |
|
|
120
|
+
| `onlineLocalizationUrl` | optional online runtime XML | URL must return parser-compatible XML |
|
|
121
|
+
| `fetchTypeLocalLocalization` | editor import | `None`, `FromGoogleSheets`, or `FromCsv` |
|
|
122
|
+
| `sheetNameFetchLocalLocalization` | local `FromGoogleSheets` | Google Sheet tab name; avoid spaces |
|
|
123
|
+
| `csvFetchLocalLocalization` | local `FromCsv` | CSV `TextAsset` imported into Unity |
|
|
124
|
+
| `fetchTypeOnlineLocalization` | editor import | `None`, `FromGoogleSheets`, or `FromCsv` |
|
|
125
|
+
| `sheetNameFetchOnlineLocalization` | online `FromGoogleSheets` | Google Sheet tab name; avoid spaces |
|
|
126
|
+
| `csvFetchOnlineLocalization` | online `FromCsv` | CSV `TextAsset` imported into Unity |
|
|
127
|
+
| `worksheetKey` | any `FromGoogleSheets` fetch | non-empty Google spreadsheet id/key |
|
|
128
|
+
|
|
129
|
+
For local imports, the editor writes fetched content into each configured language item's assigned `XML` asset path. Create placeholder XML assets and assign them before fetching.
|
|
130
|
+
|
|
131
|
+
Inspector visibility: `Worksheet Key` is shown only when at least one fetch type is `FromGoogleSheets`. CSV-only import does not require `worksheetKey`.
|
|
132
|
+
|
|
133
|
+
## Import Data Shape
|
|
134
|
+
|
|
135
|
+
Google Sheet and CSV import use the same column model:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
Key,English,Vietnamese
|
|
139
|
+
Home_Title,Home,Trang chu
|
|
140
|
+
Home_Subtitle,Welcome,Chao mung
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Rules:
|
|
144
|
+
|
|
145
|
+
- first row is header;
|
|
146
|
+
- first column is key;
|
|
147
|
+
- subsequent columns map to `localizationLanguageItems` order;
|
|
148
|
+
- column names should match the intended languages for human clarity;
|
|
149
|
+
- every data row must contain `Key` plus one cell per configured language;
|
|
150
|
+
- empty values generate empty XML text nodes;
|
|
151
|
+
- CSV delimiter is comma.
|
|
152
|
+
|
|
153
|
+
`Fetch Localization` is editor-only. It converts external data into XML and regenerates constants; runtime reads XML, Addressables XML, or online XML URL only.
|
|
154
|
+
|
|
155
|
+
## LocalizationLanguageItem API
|
|
156
|
+
|
|
157
|
+
Namespace:
|
|
158
|
+
|
|
159
|
+
```csharp
|
|
160
|
+
XmobiTea.MiniLocalization.Core
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Shape:
|
|
164
|
+
|
|
165
|
+
```csharp
|
|
166
|
+
public class LocalizationLanguageItem
|
|
167
|
+
{
|
|
168
|
+
public SystemLanguage systemLanguage { get; }
|
|
169
|
+
public Sprite flagSpr { get; }
|
|
170
|
+
public TextAsset xml { get; set; }
|
|
171
|
+
public string onlineLocalizationUrl { get; set; }
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
When Addressables is installed:
|
|
176
|
+
|
|
177
|
+
```csharp
|
|
178
|
+
public AssetReferenceT<TextAsset> xmlRef { get; set; }
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
One item can provide local XML, optional Addressables XML, and optional online XML URL for the same language.
|
|
182
|
+
|
|
183
|
+
If both `xmlRef` and `onlineLocalizationUrl` are configured, both async loads run independently. The callback that finishes later mutates the active dictionary last.
|
|
184
|
+
|
|
185
|
+
## Editor Menus
|
|
186
|
+
|
|
187
|
+
| Menu | Effect |
|
|
188
|
+
| --- | --- |
|
|
189
|
+
| `XmobiTea Tools/Localization/Open Settings` | creates or selects `Assets/Resources/XmobiTea LocalizationSettings.asset` |
|
|
190
|
+
| `XmobiTea Tools/Localization/Show LocalizationComponentWindows` | opens bulk UI text binding window |
|
|
191
|
+
| `XmobiTea Tools/Localization/Generate LocalizationConstantId.cs` | generates constants from the first language item's local XML |
|
|
192
|
+
| `XmobiTea Tools/Localization/Fetch Localization` | imports local/online XML files from configured editor sources, then regenerates constants |
|
|
193
|
+
|
|
194
|
+
Inspector buttons on `LocalizationManager` and `LocalizationSettings` mirror the window, generate, and fetch actions.
|
|
195
|
+
|
|
196
|
+
## Generated Constants
|
|
197
|
+
|
|
198
|
+
Runtime package file:
|
|
199
|
+
|
|
200
|
+
```csharp
|
|
201
|
+
namespace XmobiTea.MiniLocalization
|
|
202
|
+
{
|
|
203
|
+
public partial class LocalizationConstantId { }
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Generated file path:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
Assets/XmobiTea-constant/Scripts/LocalizationConstantId.cs
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Generated shape:
|
|
214
|
+
|
|
215
|
+
```csharp
|
|
216
|
+
namespace XmobiTea.MiniLocalization
|
|
217
|
+
{
|
|
218
|
+
public partial class LocalizationConstantId
|
|
219
|
+
{
|
|
220
|
+
public static readonly string Home_Title = "Home_Title";
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Generator behavior:
|
|
226
|
+
|
|
227
|
+
- reads only the first configured language item's local XML;
|
|
228
|
+
- converts invalid C# field-name characters to `_`;
|
|
229
|
+
- removes diacritics;
|
|
230
|
+
- prefixes digit-starting names and C# keywords with `_`;
|
|
231
|
+
- logs duplicate generated field names and skips later duplicates.
|
|
232
|
+
|
|
233
|
+
Generated members are `public static readonly string`, not `const`.
|
|
234
|
+
|
|
235
|
+
## XML Shape
|
|
236
|
+
|
|
237
|
+
Runtime parser accepts any root and section tag names as long as the document has the expected node order, keys are two levels below the root, and each key node has a `name` attribute.
|
|
238
|
+
|
|
239
|
+
Minimal valid XML:
|
|
240
|
+
|
|
241
|
+
```xml
|
|
242
|
+
<?xml version='1.0' encoding='utf-8'?>
|
|
243
|
+
<English>
|
|
244
|
+
<section name='Local'>
|
|
245
|
+
<key name='Home_Title'>Home</key>
|
|
246
|
+
</section>
|
|
247
|
+
</English>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Parser rules:
|
|
251
|
+
|
|
252
|
+
- expects the root element at `xmlDoc.ChildNodes.Item(1)`, so generated or hand-authored XML should include the XML declaration;
|
|
253
|
+
- reads `xmlDoc.ChildNodes.Item(1)` as root;
|
|
254
|
+
- loops each section node under root;
|
|
255
|
+
- loops each key node under each section;
|
|
256
|
+
- reads key from `node.Attributes.GetNamedItem("name").Value`;
|
|
257
|
+
- reads text from `node.InnerText`;
|
|
258
|
+
- logs duplicate keys and overwrites with the later value.
|
|
259
|
+
|
|
260
|
+
Text replacements after XML read:
|
|
261
|
+
|
|
262
|
+
| Stored text | Runtime text |
|
|
263
|
+
| --- | --- |
|
|
264
|
+
| `\\n` | newline |
|
|
265
|
+
| `<` | `<` |
|
|
266
|
+
| `>` | `>` |
|
|
267
|
+
| `&` | `&` |
|
|
268
|
+
| `'` | `'` |
|
|
269
|
+
| `"` | `"` |
|
|
270
|
+
|
|
271
|
+
## Error And Fallback Guards
|
|
272
|
+
|
|
273
|
+
- Missing manager: `ChooseLanguage` returns `false`; `GetText` returns the input key; language getters return `null`.
|
|
274
|
+
- Missing settings during manager init: logs `[Localization] Missing XmobiTea LocalizationSettings` and no language registry is built.
|
|
275
|
+
- Missing language in settings: `ChooseLanguage(...)` logs an error and returns `false`.
|
|
276
|
+
- Missing key: `GetText(key)` returns `key`.
|
|
277
|
+
- Empty key: `GetText(key)` returns `key`.
|
|
278
|
+
- Duplicate XML key: logs an error and overwrites with the later value.
|
|
279
|
+
- Missing local XML: local sync load is skipped; optional Addressables or online sources may still update later if configured.
|
|
280
|
+
- Missing first language XML during constant generation: generator can throw while reading or parsing.
|
|
281
|
+
- Missing CSV asset or missing CSV language columns during fetch: editor code can throw before generating XML.
|