Initial commit: Unity WordConnect project
This commit is contained in:
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a3ec51c6680c4484ae299678edb20bc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "CandySmith.Localization.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
" UnityEngine",
|
||||
" UnityEditor",
|
||||
"UnityEditor.UI",
|
||||
"Unity.TextMeshPro.Editor",
|
||||
"Unity.TextMeshPro",
|
||||
"Reordable",
|
||||
"CandySmith.BlockPuzzle.Main",
|
||||
"CandySmith.Ads",
|
||||
"CandySmith.IAP",
|
||||
"DOTween.Modules",
|
||||
"CandySmith.WordsToolkit.Main",
|
||||
"VContainer"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54ed5b0a667e4a0f987a5bacb1b15ba6
|
||||
timeCreated: 1722189029
|
||||
@ -0,0 +1,40 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(LocalizationIndex))]
|
||||
public class LocalizationDrawerUIE : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
position.height = EditorGUIUtility.singleLineHeight;
|
||||
var r1 = position;
|
||||
r1.width = 1;
|
||||
|
||||
var r2 = position;
|
||||
r2.xMin = r1.xMax + 1;
|
||||
r2.width = 50;
|
||||
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
// EditorGUI.PropertyField(r1, property.FindPropertyRelative("text"),new GUIContent("","Default text"));
|
||||
EditorGUI.PropertyField(r2, property.FindPropertyRelative("index"), new GUIContent("", "Localization line index"));
|
||||
r2.x += 50;
|
||||
r2.width = 300;
|
||||
EditorGUI.LabelField(r2, "Change text here: Resources/Localization/");
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 944cf446217df453f8452f1e796751f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,67 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(LocalizationIndexFolder))]
|
||||
public class LocalizationFoldDrawer : PropertyDrawer
|
||||
{
|
||||
private int offset;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
position.height = EditorGUIUtility.singleLineHeight;
|
||||
property.isExpanded = EditorGUI.Foldout(position, property.isExpanded, "Text");
|
||||
if (property.isExpanded)
|
||||
{
|
||||
offset = 5;
|
||||
position.y += EditorGUIUtility.singleLineHeight;
|
||||
ShowField(position, property, "description", "Description");
|
||||
position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
ShowField(position, property, "failed", "Fail Description");
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
private void ShowField(Rect position, SerializedProperty property, string field, string label)
|
||||
{
|
||||
position.x += offset;
|
||||
var r1 = position;
|
||||
r1.width = 100;
|
||||
EditorGUI.LabelField(r1, label);
|
||||
position.x += offset;
|
||||
var r2 = position;
|
||||
r2.xMin = r1.xMax + 10;
|
||||
EditorGUI.PropertyField(r2, property.FindPropertyRelative(field));
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return property.isExpanded ? EditorGUIUtility.singleLineHeight * 3 + EditorGUIUtility.standardVerticalSpacing * 2 : EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class LocalizationIndexFolder
|
||||
{
|
||||
[Tooltip("Default text")]
|
||||
public LocalizationIndex description;
|
||||
|
||||
public LocalizationIndex failed;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ceb71aa3d5e3348c6970c0b29d923e26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,33 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class LocalizationInitializer
|
||||
{
|
||||
// static LocalizationInitializer()
|
||||
// {
|
||||
// EditorApplication.delayCall += Initialize;
|
||||
// }
|
||||
//
|
||||
// static void Initialize()
|
||||
// {
|
||||
// if (!Application.isPlaying)
|
||||
// {
|
||||
// LocalizationManager.InitializeLocalization();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9a87bf82ff9497d866a51df91a94948
|
||||
timeCreated: 1722323590
|
||||
@ -0,0 +1,49 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization.Editor
|
||||
{
|
||||
public class LocalizedTextMeshProUGUICreator
|
||||
{
|
||||
[MenuItem("GameObject/UI/Localized TextMeshPro - Text (UI)")]
|
||||
private static void CreateLocalizedTextMeshProUGUI()
|
||||
{
|
||||
// Create a new GameObject
|
||||
var go = new GameObject("Localized TextMeshPro");
|
||||
|
||||
// Add the LocalizedTextMeshProUGUI component
|
||||
var localizedText = go.AddComponent<LocalizedTextMeshProUGUI>();
|
||||
|
||||
localizedText.fontSize = 32;
|
||||
localizedText.enableAutoSizing = true;
|
||||
localizedText.fontSizeMin = 16;
|
||||
localizedText.fontSizeMax = 200;
|
||||
localizedText.alignment = TextAlignmentOptions.Center;
|
||||
|
||||
// Set the parent of the new object
|
||||
if (Selection.activeGameObject != null)
|
||||
{
|
||||
go.transform.SetParent(Selection.activeGameObject.transform, false);
|
||||
}
|
||||
|
||||
// Register the creation for undo
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create Localized TextMeshPro");
|
||||
|
||||
// Select the newly created object
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f8e705c10b94f8dbed011f2760f1cac
|
||||
timeCreated: 1722330317
|
||||
@ -0,0 +1,99 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro.EditorUtilities;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization.Editor
|
||||
{
|
||||
[CustomEditor(typeof(LocalizedTextMeshProUGUI), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class LocalizedTextMeshProUGUIEditor : TMP_EditorPanelUI
|
||||
{
|
||||
private SerializedProperty instanceIDProp;
|
||||
private LocalizedTextMeshProUGUI localizedText;
|
||||
private string lastKnownName;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
instanceIDProp = serializedObject.FindProperty("instanceID");
|
||||
localizedText = (LocalizedTextMeshProUGUI)target;
|
||||
lastKnownName = localizedText.gameObject.name;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
if (localizedText != null && localizedText.gameObject.name != lastKnownName)
|
||||
{
|
||||
localizedText.text = localizedText.gameObject.name;
|
||||
lastKnownName = localizedText.gameObject.name;
|
||||
EditorUtility.SetDirty(localizedText);
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(instanceIDProp);
|
||||
|
||||
if (GUILayout.Button("Edit Localization"))
|
||||
{
|
||||
string relativePath = "Assets/WordConnectGameToolkit/Resources/Localization/English.txt";
|
||||
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(relativePath);
|
||||
if (asset != null)
|
||||
{
|
||||
AssetDatabase.OpenAsset(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("English.txt file not found at: " + relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck() || Event.current.type == EventType.Layout)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
UpdateLocalizedText();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
UpdateLocalizedText();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLocalizedText()
|
||||
{
|
||||
if (localizedText != null && !string.IsNullOrEmpty(localizedText.instanceID))
|
||||
{
|
||||
var originalText = localizedText.text;
|
||||
var localizedString = LocalizationManager.instance.GetText(localizedText.instanceID, originalText);
|
||||
if (localizedText.text != localizedString)
|
||||
{
|
||||
localizedText.text = localizedString;
|
||||
|
||||
if (PrefabUtility.IsPartOfPrefabInstance(localizedText))
|
||||
{
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(localizedText);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(localizedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ee5acd244824d7bbd981db5e537507f
|
||||
timeCreated: 1722188512
|
||||
@ -0,0 +1,111 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Reflection;
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization.Editor
|
||||
{
|
||||
public class TextMeshProReplacer : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/Replace TMP with LocalizedTMP")]
|
||||
private static void ReplaceTextMeshProUGUI()
|
||||
{
|
||||
var selectedObjects = Selection.gameObjects;
|
||||
|
||||
if (selectedObjects.Length == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("No Selection", "Please select at least one GameObject.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
var replacedCount = 0;
|
||||
|
||||
foreach (var obj in selectedObjects)
|
||||
{
|
||||
var tmproComponents = obj.GetComponentsInChildren<TextMeshProUGUI>(true);
|
||||
foreach (var tmproComponent in tmproComponents)
|
||||
{
|
||||
if (tmproComponent.GetType() == typeof(TextMeshProUGUI)) // Ensure we're not replacing already customized scripts
|
||||
{
|
||||
var localizeText = tmproComponent.GetComponent<LocalizeText>();
|
||||
var instanceID = localizeText != null ? localizeText.instanceID : "";
|
||||
|
||||
// Store all relevant properties
|
||||
var text = tmproComponent.text;
|
||||
var font = tmproComponent.font;
|
||||
var fontMaterial = tmproComponent.fontMaterial;
|
||||
var color = tmproComponent.color;
|
||||
var fontStyle = tmproComponent.fontStyle;
|
||||
var fontSize = tmproComponent.fontSize;
|
||||
var autoSizeTextContainer = tmproComponent.autoSizeTextContainer;
|
||||
var enableAutoSizing = tmproComponent.enableAutoSizing;
|
||||
var characterSpacing = tmproComponent.characterSpacing;
|
||||
var wordSpacing = tmproComponent.wordSpacing;
|
||||
var lineSpacing = tmproComponent.lineSpacing;
|
||||
var paragraphSpacing = tmproComponent.paragraphSpacing;
|
||||
var alignment = tmproComponent.alignment;
|
||||
var enableWordWrapping = tmproComponent.enableWordWrapping;
|
||||
var overflowMode = tmproComponent.overflowMode;
|
||||
var isRightToLeftText = tmproComponent.isRightToLeftText;
|
||||
var enableKerning = tmproComponent.enableKerning;
|
||||
var extraPadding = tmproComponent.extraPadding;
|
||||
var richText = tmproComponent.richText;
|
||||
|
||||
// Remove old component
|
||||
DestroyImmediate(tmproComponent);
|
||||
if (localizeText != null)
|
||||
{
|
||||
DestroyImmediate(localizeText);
|
||||
}
|
||||
|
||||
// Add new component
|
||||
var newComponent = obj.AddComponent<LocalizedTextMeshProUGUI>();
|
||||
|
||||
// Restore properties
|
||||
newComponent.text = text;
|
||||
newComponent.font = font;
|
||||
newComponent.fontMaterial = fontMaterial;
|
||||
newComponent.color = color;
|
||||
newComponent.fontStyle = fontStyle;
|
||||
newComponent.fontSize = fontSize;
|
||||
newComponent.autoSizeTextContainer = autoSizeTextContainer;
|
||||
newComponent.enableAutoSizing = enableAutoSizing;
|
||||
newComponent.characterSpacing = characterSpacing;
|
||||
newComponent.wordSpacing = wordSpacing;
|
||||
newComponent.lineSpacing = lineSpacing;
|
||||
newComponent.paragraphSpacing = paragraphSpacing;
|
||||
newComponent.alignment = alignment;
|
||||
newComponent.enableWordWrapping = enableWordWrapping;
|
||||
newComponent.overflowMode = overflowMode;
|
||||
newComponent.isRightToLeftText = isRightToLeftText;
|
||||
newComponent.enableKerning = enableKerning;
|
||||
newComponent.extraPadding = extraPadding;
|
||||
newComponent.richText = richText;
|
||||
|
||||
// Set the instanceID using reflection (since it's private)
|
||||
var fieldInfo = typeof(LocalizedTextMeshProUGUI).GetField("instanceID", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
fieldInfo.SetValue(newComponent, instanceID);
|
||||
}
|
||||
|
||||
replacedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorUtility.DisplayDialog("Replacement Complete", $"Replaced {replacedCount} TextMeshProUGUI component(s) with LocalizedTextMeshProUGUI.", "OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f2acec46fea4a4283963e2e0a1dc627
|
||||
timeCreated: 1722188160
|
||||
@ -0,0 +1,27 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
public interface ILocalizationService
|
||||
{
|
||||
string GetText(string key, string defaultText);
|
||||
SystemLanguage GetCurrentLanguage();
|
||||
void LoadLanguage(SystemLanguage language);
|
||||
void LoadLanguageFromBase(TextAsset localizationBase);
|
||||
public void SetKeysPlaceholders(Dictionary<string, string> keys);
|
||||
public void SetPairPlaceholder(string key, string value);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b18fe539f7e834fa09fd73d9340bc844
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,24 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
[Serializable]
|
||||
public class LanguageObject
|
||||
{
|
||||
public SystemLanguage language;
|
||||
public string text;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8d31ef4542740f7804a1c8570aaaa33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,27 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
[Serializable]
|
||||
public class LocalizationIndex
|
||||
{
|
||||
[Tooltip("Default text")]
|
||||
public string text;
|
||||
|
||||
[Tooltip("Localization line index")]
|
||||
public int index;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8f88401902cf49958b68ffe4f733a34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,215 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
using WordsToolkit.Scripts.Levels;
|
||||
using WordsToolkit.Scripts.Services;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
public class LocalizationManager : SingletonBehaviour<LocalizationManager>, ILocalizationService
|
||||
{
|
||||
private static DebugSettings _debugSettings;
|
||||
public static Dictionary<string, string> _dic;
|
||||
private SystemLanguage _currentLanguage;
|
||||
[Inject]
|
||||
private LanguageConfiguration languageConfig;
|
||||
[Inject]
|
||||
private ILanguageService languageService;
|
||||
|
||||
private Dictionary<string, string> _placeholdersDic;
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
InitializeLocalization();
|
||||
}
|
||||
|
||||
public void InitializeLocalization()
|
||||
{
|
||||
_debugSettings = Resources.Load("Settings/DebugSettings") as DebugSettings;
|
||||
LoadLanguage(GetSystemLanguage());
|
||||
}
|
||||
|
||||
public void SetKeysPlaceholders(Dictionary<string, string> keys)
|
||||
{
|
||||
if (keys == null || keys.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("Localization keys are null or empty. Using default language.");
|
||||
LoadLanguage(SystemLanguage.English);
|
||||
return;
|
||||
}
|
||||
|
||||
_placeholdersDic = new Dictionary<string, string>(keys);
|
||||
}
|
||||
|
||||
public void SetPairPlaceholder(string key, string value)
|
||||
{
|
||||
_placeholdersDic ??= new Dictionary<string, string>();
|
||||
_placeholdersDic[key] = value;
|
||||
}
|
||||
|
||||
public void LoadLanguage(SystemLanguage language)
|
||||
{
|
||||
_currentLanguage = language;
|
||||
// Convert language enum to CultureInfo to get the actual file name
|
||||
var cultureInfo = CultureInfo.GetCultures(CultureTypes.AllCultures)
|
||||
.FirstOrDefault(c => string.Equals(c.EnglishName, language.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var fileName = cultureInfo != null ? cultureInfo.EnglishName : language.ToString();
|
||||
var txt = Resources.Load<TextAsset>($"Localization/{fileName}");
|
||||
if (txt == null)
|
||||
{
|
||||
Debug.LogWarning($"Localization file for {fileName} not found. Falling back to English.");
|
||||
txt = Resources.Load<TextAsset>("Localization/English");
|
||||
_currentLanguage = SystemLanguage.English;
|
||||
}
|
||||
|
||||
_dic = new Dictionary<string, string>();
|
||||
var lines = txt.text.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var inp_ln in lines)
|
||||
{
|
||||
var l = inp_ln.Split(new[] { ':' }, 2);
|
||||
if (l.Length == 2)
|
||||
{
|
||||
var key = l[0].Trim();
|
||||
var text = l[1].Trim();
|
||||
_dic[key] = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadLanguageFromBase(TextAsset localizationBase)
|
||||
{
|
||||
if (localizationBase == null)
|
||||
{
|
||||
Debug.LogWarning("Localization base is null. Falling back to English.");
|
||||
LoadLanguage(SystemLanguage.English);
|
||||
return;
|
||||
}
|
||||
|
||||
_dic = new Dictionary<string, string>();
|
||||
var lines = localizationBase.text.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var inp_ln in lines)
|
||||
{
|
||||
var l = inp_ln.Split(new[] { ':' }, 2);
|
||||
if (l.Length == 2)
|
||||
{
|
||||
var key = l[0].Trim();
|
||||
var text = l[1].Trim();
|
||||
_dic[key] = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SystemLanguage GetSystemLanguage()
|
||||
{
|
||||
if (_debugSettings == null)
|
||||
{
|
||||
_debugSettings = Resources.Load("Settings/DebugSettings") as DebugSettings;
|
||||
}
|
||||
|
||||
// Try to get language from LanguageService if available
|
||||
if (instance != null && instance.languageService != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var languageCode = instance.languageService.GetCurrentLanguageCode();
|
||||
var cultureInfo = new CultureInfo(languageCode);
|
||||
return (SystemLanguage)Enum.Parse(typeof(SystemLanguage), cultureInfo.EnglishName);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Fallback if there's an issue parsing the language code
|
||||
Debug.LogWarning("Failed to parse language from LanguageService. Using fallback.");
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to PlayerPrefs check for backward compatibility
|
||||
if (PlayerPrefs.HasKey("SelectedLanguage"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var value = PlayerPrefs.GetString("SelectedLanguage");
|
||||
var cultureInfo = new CultureInfo(value);
|
||||
return (SystemLanguage)Enum.Parse(typeof(SystemLanguage), cultureInfo.EnglishName);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Debug.LogWarning("Failed to parse saved language preference. Using default.");
|
||||
}
|
||||
}
|
||||
|
||||
if (Application.isEditor)
|
||||
{
|
||||
return _debugSettings.TestLanguage;
|
||||
}
|
||||
|
||||
return Application.systemLanguage;
|
||||
}
|
||||
|
||||
public string GetText(string key, string defaultText)
|
||||
{
|
||||
var currentLanguage = GetSystemLanguage();
|
||||
if (_currentLanguage != currentLanguage || _dic == null || _dic.Count == 0)
|
||||
{
|
||||
LoadLanguage(currentLanguage);
|
||||
}
|
||||
|
||||
if (!_dic.ContainsKey(key))
|
||||
{
|
||||
LoadLanguage(currentLanguage);
|
||||
}
|
||||
|
||||
if (_dic.TryGetValue(key, out var localizedText) && !string.IsNullOrEmpty(localizedText))
|
||||
{
|
||||
return PlaceholderManager.ReplacePlaceholders(localizedText, _placeholdersDic);
|
||||
}
|
||||
|
||||
return PlaceholderManager.ReplacePlaceholders(defaultText, _placeholdersDic);
|
||||
}
|
||||
|
||||
public SystemLanguage GetCurrentLanguage()
|
||||
{
|
||||
return _currentLanguage;
|
||||
}
|
||||
|
||||
public string GetLocalizedCurrentLanguage()
|
||||
{
|
||||
if (languageService != null)
|
||||
{
|
||||
var currentLanguageInfo = languageService.GetCurrentLanguageInfo();
|
||||
if (currentLanguageInfo != null)
|
||||
{
|
||||
return currentLanguageInfo.localizedName;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to old logic
|
||||
foreach (var lang in languageConfig.languages)
|
||||
{
|
||||
if (lang.displayName == _currentLanguage.ToString())
|
||||
{
|
||||
return lang.localizedName;
|
||||
}
|
||||
}
|
||||
return _currentLanguage.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4ba3c33f9f6741ce8e89e40c09c2af2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 800
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,88 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Settings;
|
||||
using WordsToolkit.Scripts.Unity_Reorderable_List_master.List;
|
||||
using WordsToolkit.Scripts.Unity_Reorderable_List_master.List.Attributes;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
public class LocalizeText : MonoBehaviour
|
||||
{
|
||||
private TextMeshProUGUI textObject;
|
||||
public string instanceID;
|
||||
|
||||
[SerializeField]
|
||||
[Reorderable(elementNameProperty = "language")]
|
||||
[HideInInspector]
|
||||
public MyList objects;
|
||||
|
||||
private string _originalText;
|
||||
private string _currentText;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
textObject = GetComponent<TextMeshProUGUI>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
//take text from target editor
|
||||
_originalText = textObject.text;
|
||||
_currentText = LocalizationManager.instance.GetText(instanceID, _originalText);
|
||||
textObject.text = _currentText;
|
||||
}
|
||||
|
||||
// private void Update()
|
||||
// {
|
||||
// if (_currentText != "")
|
||||
// {
|
||||
// textObject.text = _currentText;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MyList : ReorderableArray<LanguageObject>
|
||||
{
|
||||
private SystemLanguage GetSystemLanguage(DebugSettings _debugSettings)
|
||||
{
|
||||
SystemLanguage lang;
|
||||
if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.LinuxEditor)
|
||||
{
|
||||
lang = _debugSettings.TestLanguage;
|
||||
}
|
||||
else
|
||||
{
|
||||
lang = Application.systemLanguage;
|
||||
}
|
||||
|
||||
return this.Any(i => i.language == lang) ? _debugSettings.TestLanguage : SystemLanguage.English;
|
||||
}
|
||||
|
||||
public IEnumerable<LanguageObject> GetText(DebugSettings _debugSettings)
|
||||
{
|
||||
var systemLanguage = GetSystemLanguage(_debugSettings);
|
||||
return GetText(systemLanguage);
|
||||
}
|
||||
|
||||
public IEnumerable<LanguageObject> GetText(SystemLanguage systemLanguage)
|
||||
{
|
||||
return this.Where(i => i.language == systemLanguage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32729a099b98b485a9563986a3d5ef3d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 1900
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,48 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
public class LocalizedTextMeshProUGUI : TextMeshProUGUI
|
||||
{
|
||||
[SerializeField]
|
||||
public string instanceID;
|
||||
|
||||
private string originalText;
|
||||
private ILocalizationService _localizationService;
|
||||
|
||||
[Inject]
|
||||
public void Construct(ILocalizationService localizationService)
|
||||
{
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
originalText = text;
|
||||
UpdateText();
|
||||
}
|
||||
|
||||
public void UpdateText()
|
||||
{
|
||||
if (instanceID != "")
|
||||
{
|
||||
text = _localizationService?.GetText(instanceID, originalText) ?? originalText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bc838cbc2e148b3a5e7578d063ccb18
|
||||
timeCreated: 1722187699
|
||||
@ -0,0 +1,60 @@
|
||||
// // ©2015 - 2025 Candy Smith
|
||||
// // All rights reserved
|
||||
// // Redistribution of this software is strictly not allowed.
|
||||
// // Copy of this software can be obtained from unity asset store only.
|
||||
// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// // THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using WordsToolkit.Scripts.Gameplay.Managers;
|
||||
using WordsToolkit.Scripts.System;
|
||||
|
||||
namespace WordsToolkit.Scripts.Localization
|
||||
{
|
||||
// This class is used to replace placeholders in localized strings with actual values.
|
||||
public static class PlaceholderManager
|
||||
{
|
||||
public static string GetPlaceholderValue(string placeholderKey, Dictionary<string, string> placeholdersDic)
|
||||
{
|
||||
// First check if the key exists in the provided dictionary
|
||||
if (placeholdersDic != null && placeholdersDic.TryGetValue(placeholderKey, out string value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// If not found in dictionary, check default cases
|
||||
switch (placeholderKey)
|
||||
{
|
||||
case "level":
|
||||
return GetCurrentLevel().ToString();
|
||||
default:
|
||||
if (PlayerPrefs.HasKey(placeholderKey))
|
||||
{
|
||||
return PlayerPrefs.GetString(placeholderKey);
|
||||
}
|
||||
return "{" + placeholderKey + "}";
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReplacePlaceholders(string input, Dictionary<string, string> placeholdersDic)
|
||||
{
|
||||
return Regex.Replace(input, @"\{(\w+)\}", match =>
|
||||
{
|
||||
var placeholderKey = match.Groups[1].Value;
|
||||
return GetPlaceholderValue(placeholderKey, placeholdersDic);
|
||||
});
|
||||
}
|
||||
|
||||
private static int GetCurrentLevel()
|
||||
{
|
||||
return GameDataManager.GetLevel().number;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fac86d0fb1f54ae1a60853746bd7fb7b
|
||||
timeCreated: 1725684738
|
||||
Reference in New Issue
Block a user