Tanoda
Localization_SOURCE.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using GILES;
4using UnityEngine;
5using UnityEngine.UI;
6using Object = UnityEngine.Object;
7
8//---Written by Matej Vanco 20.10.2018 dd/mm/yyyy
9//---Updated by Matej Vanco 05.01.2021 dd/mm/yyyy
10//---Language Localization - Source
11//Contact me here if anything happen: https://matejvanco.com/contact
12
13[AddComponentMenu("Matej Vanco/Language Localization")]
14public class Localization_SOURCE : MonoBehaviour
15{
17
18 //Values are editable-----------------
19 public static string GENERAL_DelimiterSymbol_Category = ">"; //This delimiter corresponds to custom categories
20 public static string GENERAL_DelimiterSymbol_Key = "="; //This delimiter splits key & it's content in text
21
22 public static string GENERAL_NewLineSymbol = "/l"; //This delimiter splits new lines
23 //------------------------------------------
24
25 public TextAsset[] LanguageFiles;
26 public int SelectedLanguage;
27
28 public bool LoadLanguageOnStart = true;
29
30 public List<string> Categories = new List<string>();
31
32 [Serializable]
34 {
35 public enum _AssignationType
36 {
37 GameObjectChild,
38 LocalizationComponent,
39 SpecificUIText,
40 SpecificTextMesh,
41 TextReplacer,
42 AutoFindText
43 }
44
46
47 //Essentials
48 public string Key;
49 public string Text;
50 public int Category;
51
52 //AT - GameObjectChild
53 public bool AT_FindChildByKeyName = true;
54 public string AT_ChildName;
56 public Transform AT_CustomChildsRootObject;
57
58 //AT - Allowed Types
59 public bool AT_UITextComponentAllowed = true;
60 public bool AT_TextMeshComponentAllowed = true;
61
62 //AT - Available Objects
63 public List<GameObject> AT_FoundObjects = new List<GameObject>();
64
65 //AT - Specific_UIText
67
68 //AT - Specific_UIDropdown
70
71 //AT - Specific_TextMesh
72 public TextMesh[] AT_TextMeshbject;
73 }
74
75 public List<_LocalizationSelector> LocalizationSelector = new List<_LocalizationSelector>();
76 public Transform AT_GameObjectChildsRoot;
77 public GameObject ExtraCanvas1;
78 public GameObject ExtraCanvas2;
79 public GameObject ExtraCanvas3;
80
81 public int selectedCategory;
82
83 [Serializable]
84 public class QuickActions
85 {
87
88 [Tooltip(
89 "If assignation type is set to GameObjectChild & the bool is set to True, the target text will be searched in the global Childs root object")]
90 public bool useGeneralChildsRoot = true;
91
92 [Space] [Tooltip("Allow UIText component?")]
93 public bool UITextAllowed = true;
94
95 [Tooltip("Allow TextMesh component?")] public bool TextMeshAllowed = true;
96
97 [Space] [Tooltip("New specific UI Texts")]
98 public Text[] SpecificUITexts;
99
100 [Tooltip("New specific Text Meshes")] public TextMesh[] SpecificTextMeshes;
101
102 [Tooltip(
103 "If enabled, the object fields above will be cleared if the QuickActions are applied to key in specific category")]
104 public bool ClearAllPreviousTargets = true;
105 }
106
108 //Quick actions allow user to manipulate with exist keys much faster!
109
110 private void Awake()
111 {
112 if (!Application.isPlaying) return;
113
114 if (!Instance) Instance = this;
115
119 }
120
121 #region INTERNAL METHODS
122
123#if UNITY_EDITOR
124
125 internal void Internal_RefreshInternalLocalization()
126 {
127 Categories.Clear();
128 Categories.AddRange(Localization_SOURCE_Window.locAvailableCategories);
129 }
130
131 internal void Internal_AddKey(string KeyName)
132 {
133 foreach (var a in Localization_SOURCE_Window.localizationElements)
134 if (a.Key == KeyName)
135 {
136 LocalizationSelector.Add(new _LocalizationSelector
137 {
138 Key = a.Key,
139 Text = a.Text,
140 Category = a.Category,
141 AssignationType = _LocalizationSelector._AssignationType.AutoFindText
142 });
143 return;
144 }
145 }
146
147#endif
148
149 public void ReloadLanguage(GameObject onlyThis = null)
150 {
153 }
154
155 private string Internal_ConvertAndReturnText(_LocalizationSelector lSelector, string[] lines)
156 {
157 if (lines.Length > 1)
158 {
159 var storedFilelines = new List<string>();
160 for (var i = 1; i < lines.Length; i++)
161 storedFilelines.Add(lines[i]);
162
163 foreach (var categories in Categories)
164 if (Internal_GetLocalizationCategory(categories) == lSelector.Category)
165 foreach (var s in storedFilelines)
166 {
167 if (string.IsNullOrEmpty(s))
168 continue;
169 if (s.StartsWith(GENERAL_DelimiterSymbol_Category))
170 continue;
171 var del = s.IndexOf(GENERAL_DelimiterSymbol_Key);
172 if (del == 0 || del > s.Length) continue;
173
174 var Key = s.Substring(0, del);
175
176 if (string.IsNullOrEmpty(Key)) continue;
177 if (Key == lSelector.Key)
178 {
179 if (s.Length < Key.Length + 1)
180 continue;
181 lSelector.Text = s.Substring(Key.Length + 1, s.Length - Key.Length - 1);
182 return lSelector.Text;
183 }
184 }
185 }
186
187 return "";
188 }
189
190 internal int Internal_GetLocalizationCategory(string entry)
191 {
192 var c = 0;
193 foreach (var categ in Categories)
194 {
195 if (categ == entry) return c;
196 c++;
197 }
198
199 return 0;
200 }
201
202 #endregion
203
207 public void Lang_RefreshKeyAssignations(GameObject useThis = null)
208 {
209 foreach (var sel in LocalizationSelector)
210 {
211 switch (sel.AssignationType)
212 {
213 case _LocalizationSelector._AssignationType.GameObjectChild:
214 var childName = sel.AT_ChildName;
215 if (sel.AT_FindChildByKeyName)
216 childName = sel.Key;
217
218 sel.AT_FoundObjects.Clear();
219 var root = sel.AT_UseGeneralChildsRootObject
221 : sel.AT_CustomChildsRootObject;
222
223 if (useThis) root = useThis.transform;
224
225 if (!root)
226 {
227 Debug.LogError("Localization: The key '" + sel.Key +
228 "' should have been assigned to specific childs by it's key name, but the root object is empty");
229 return;
230 }
231
232 foreach (var t in root.GetComponentsInChildren<Transform>(true))
233 {
234 if (t.name != childName) continue;
235
236 if (sel.AT_UITextComponentAllowed && t.GetComponent<Text>())
237 sel.AT_FoundObjects.Add(t.gameObject);
238 if (sel.AT_TextMeshComponentAllowed && t.GetComponent<TextMesh>())
239 sel.AT_FoundObjects.Add(t.gameObject);
240 }
241
242 break;
243
244 case _LocalizationSelector._AssignationType.LocalizationComponent:
245 sel.AT_FoundObjects.Clear();
246 foreach (var k in FindObjectsOfType<Localization_KEY>())
247 if (k.KeyID == sel.Key)
248 sel.AT_FoundObjects.Add(k.gameObject);
249 break;
250 case _LocalizationSelector._AssignationType.TextReplacer:
251 sel.AT_FoundObjects.Clear();
252 foreach (var text in sel.AT_UITextObject)
253 if (text.text == sel.Key)
254 sel.AT_FoundObjects.Add(text.gameObject);
255 break;
256 case _LocalizationSelector._AssignationType.AutoFindText:
257 sel.AT_FoundObjects.Clear();
258 if (useThis)
259 {
260 var aa = FindTextRecursive(useThis, sel.Key);
261 sel.AT_FoundObjects.AddRange(aa);
262 break;
263 }
264
265 var texts = FindTextRecursive(AT_GameObjectChildsRoot.gameObject, sel.Key);
266 sel.AT_FoundObjects.AddRange(texts);
267 if (ExtraCanvas1)
268 sel.AT_FoundObjects.AddRange(FindTextRecursive(ExtraCanvas1, sel.Key));
269 if (ExtraCanvas2)
270 sel.AT_FoundObjects.AddRange(FindTextRecursive(ExtraCanvas2, sel.Key));
271 if (ExtraCanvas3)
272 sel.AT_FoundObjects.AddRange(FindTextRecursive(ExtraCanvas3, sel.Key));
273 break;
274 }
275
276 if (sel.AssignationType == _LocalizationSelector._AssignationType.GameObjectChild ||
277 sel.AssignationType == _LocalizationSelector._AssignationType.LocalizationComponent) continue;
278 //if (sel.AT_FoundObjects.Count == 0)
279 // Debug.Log("Localization: The key '" + sel.Key + "' couldn't find any child objects");
280 }
281 }
282
283 private GameObject[] FindTextRecursive(GameObject go, string text)
284 {
285 var returnList = new List<GameObject>();
286 foreach (Transform child in go.transform)
287 {
288 var textcomp = child.GetComponent<Text>();
289 if (textcomp && textcomp.text == text) returnList.Add(child.gameObject);
290 var tooltextcomp = child.GetComponent<pb_ToolbarButton>();
291 if (tooltextcomp && tooltextcomp.tooltip == text) returnList.Add(child.gameObject);
292 var tooltipcomp = child.GetComponent<pb_TooltipOverrider>();
293 if (tooltipcomp && tooltipcomp.newTooltip == text) returnList.Add(child.gameObject);
294 var ddown = child.GetComponent<Dropdown>();
295 if (ddown)
296 foreach (var data in ddown.options)
297 {
298 if (data.text != text) continue;
299 returnList.Add(child.gameObject);
300 }
301
302 if (child.childCount > 0)
303 {
304 var retval = FindTextRecursive(child.gameObject, text);
305 if (retval != null && retval.Length > 0) returnList.AddRange(retval);
306 }
307 }
308
309 return returnList.ToArray();
310 }
311
315 public void Lang_LoadLanguage(int languageIndex)
316 {
317 if (LanguageFiles.Length <= languageIndex)
318 {
319 Debug.LogError("Localization: The index for language selection is incorrect! Languages count: " +
320 LanguageFiles.Length + ", Your index: " + languageIndex);
321 return;
322 }
323
324 if (LanguageFiles[languageIndex] == null)
325 {
326 Debug.LogError("Localization: The language that you've selected is empty!");
327 return;
328 }
329
330 foreach (var sel in LocalizationSelector)
331 {
332 sel.Text = Internal_ConvertAndReturnText(sel, LanguageFiles[languageIndex].text.Split('\n'))
333 .Replace(GENERAL_NewLineSymbol, Environment.NewLine);
334
335 switch (sel.AssignationType)
336 {
337 case _LocalizationSelector._AssignationType.LocalizationComponent:
338 case _LocalizationSelector._AssignationType.GameObjectChild:
339 case _LocalizationSelector._AssignationType.AutoFindText:
340 foreach (var gm in sel.AT_FoundObjects)
341 if (gm.GetComponent<Text>() && sel.AT_UITextComponentAllowed)
342 {
343 gm.GetComponent<Text>().text = sel.Text;
344 }
345 else if (gm.GetComponent<TextMesh>() && sel.AT_TextMeshComponentAllowed)
346 {
347 gm.GetComponent<TextMesh>().text = sel.Text;
348 }
349 else if (gm.GetComponent<pb_TooltipOverrider>())
350 {
351 gm.GetComponent<pb_TooltipOverrider>().newTooltip = sel.Text;
352 }
353 else if (gm.GetComponent<pb_ToolbarButton>())
354 {
355 gm.GetComponent<pb_ToolbarButton>().tooltip = sel.Text;
356 }
357 else if (gm.GetComponent<Dropdown>())
358 {
359 var dd = gm.GetComponent<Dropdown>();
360 foreach (var optionData in dd.options)
361 {
362 if (optionData.text != sel.Key) continue;
363 optionData.text = sel.Text;
364 }
365 }
366
367 break;
368
369 case _LocalizationSelector._AssignationType.SpecificTextMesh:
370 foreach (var t in sel.AT_TextMeshbject)
371 {
372 if (t == null) continue;
373 t.text = sel.Text;
374 }
375
376 break;
377
378 case _LocalizationSelector._AssignationType.SpecificUIText:
379 foreach (var t in sel.AT_UITextObject)
380 {
381 if (t == null) continue;
382 t.text = sel.Text;
383 }
384
385 break;
386
387 case _LocalizationSelector._AssignationType.TextReplacer:
388 foreach (var dyn in sel.AT_UIObjects)
389 {
390 if (dyn is GameObject go)
391 {
392 var txt = go.GetComponent<Text>();
393 var ddown = go.GetComponent<Dropdown>();
394 if (txt)
395 {
396 if (txt.text != sel.Key) continue;
397 txt.text = sel.Text;
398 }
399
400 if (ddown)
401 foreach (var data in ddown.options)
402 {
403 if (data.text != sel.Key) continue;
404 data.text = sel.Text;
405 }
406 }
407
408 if (dyn is Text t)
409 {
410 if (t.text != sel.Key) continue;
411 t.text = sel.Text;
412 }
413
414 if (dyn is Dropdown d)
415 foreach (var data in d.options)
416 {
417 if (data.text != sel.Key) continue;
418 data.text = sel.Text;
419 }
420 }
421
422 break;
423 }
424 }
425 }
426
427 public string TranslateText(string key)
428 {
429 foreach (var sel in LocalizationSelector)
430 if (sel.Key == key)
431 return sel.Text;
432 Debug.Log($"Translation for '{key}' not found!");
433 return key;
434 }
435
439 public string Lang_ReturnText(string KeyInput)
440 {
441 foreach (var l in LocalizationSelector)
442 if (l.Key == KeyInput)
443 return l.Text;
444 Debug.Log("Localization: Key '" + KeyInput + "' couldn't be found");
445 return "";
446 }
447
448#if UNITY_EDITOR
449
453 [ContextMenu("Load Language")]
454 public void Lang_LoadLanguage()
455 {
458 }
459
460#endif
461}
UnityEngine.Debug Debug
Definition: TanodaServer.cs:19
_LocalizationSelector._AssignationType assignationType
static string GENERAL_NewLineSymbol
static string GENERAL_DelimiterSymbol_Key
void Lang_RefreshKeyAssignations(GameObject useThis=null)
Refresh all resource objects by selected options
string TranslateText(string key)
void Lang_LoadLanguage(int languageIndex)
Load language database by the selected language index
string Lang_ReturnText(string KeyInput)
Return exists text by the specific key input
static string GENERAL_DelimiterSymbol_Category
List< string > Categories
List< _LocalizationSelector > LocalizationSelector
static Localization_SOURCE Instance
void ReloadLanguage(GameObject onlyThis=null)
UnityEngine.Object Object