public static int FindEmptyValues(LocalisationTable locTable, LocalisationKeySchema currentSchema, bool fixMissing = false) { var emptyValues = 0; foreach (var category in currentSchema.categories) { if (category == null || category.keys == null) { continue; } foreach (var key in category.keys) { var locKeyCRC = CrcUtils.GetCrc(category.name, key); var locValue = string.Empty; try { locValue = locTable.GetString(locKeyCRC); } catch { if (fixMissing) { locTable.SetData(locKeyCRC, string.Empty); } } if (string.IsNullOrEmpty(locValue)) { emptyValues++; } } } return(emptyValues); }
/// <summary> /// Generates the LocalisationConfig class from the supplied key schema - this allows application-side code to access the available keys /// and request localised content with them. Also exports some cross functionality such as the Localisation folder path which the application /// will need. /// </summary> public static void GenerateLocalisationConfig(TextAsset configTemplate, LocalisationKeySchema schema) { if (configTemplate == null) { throw new Exception("No template supplied - can't generate localisation config file"); } var filePath = $"{Application.dataPath}/{LocalisationSettings.Current.CodeGenerationFilePath}"; var directoryPath = Path.GetDirectoryName(filePath); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } if (File.Exists(filePath)) { var renamedPath = filePath + CONFIG_REPLACE_SUFFIX; if (File.Exists(renamedPath)) { File.Delete(renamedPath); } File.Delete(filePath); } Debug.Log("Writing to " + filePath); var totalKeys = 0; var stringBuilder = new StringBuilder(); foreach (var category in schema.categories) { stringBuilder.AppendLine($"\t\tpublic enum {category.name}"); stringBuilder.AppendLine("\t\t{"); for (var i = 0; i < category.keys.Length; i++) { var key = category.keys[i]; stringBuilder.Append("\t\t\t" + key + " = " + CrcUtils.GetCrc(category.name, key)); if (i < category.keys.Length - 1) { stringBuilder.AppendLine(","); } else { stringBuilder.AppendLine(); } } stringBuilder.AppendLine("\t\t}"); totalKeys += category.keys.Length; } var outputText = configTemplate.text; outputText = outputText.Replace("{CLASS}", CONFIG_LOC_CLASS_NAME); outputText = outputText.Replace("{KEYS}", stringBuilder.ToString()); File.WriteAllText(filePath, outputText); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); Debug.Log($"Successfully generated {totalKeys} localisation keys."); }
private string DrawProperty(Rect rect, SerializedProperty property, LocalisationSettings settings) { var currentSchema = settings.Schema; var keyName = property.FindPropertyRelative("keyName"); var categoryName = property.FindPropertyRelative("categoryName"); var localisationKey = property.FindPropertyRelative("localisationKey"); var keyLookup = currentSchema.FindKey( categoryName.stringValue, keyName.stringValue); if (!isInitialized) { selectedKeyAndCategory = keyLookup.IsValid ? new Vector2Int { x = Math.Max(0, keyLookup.keyIndex), y = Math.Max(0, keyLookup.categoryIndex), } : Vector2Int.zero; isInitialized = true; } // CATEGORIES var categories = currentSchema.categories; if (categories.Length == 0) { return("No categories found. Add some to the schema"); } var categoryNames = categories.Select(c => c.name).ToArray(); var categoryIndex = selectedKeyAndCategory.y; categoryIndex = categoryIndex < 0 || categoryIndex >= categoryNames.Length ? 0 : selectedKeyAndCategory.y; var categoryRect = new Rect(rect) { x = rect.x + INDENTATION, y = rect.y + LINE_HEIGHT, height = LINE_HEIGHT, width = rect.width - INDENTATION, }; categoryIndex = EditorGUI.Popup(categoryRect, "Category", categoryIndex, categoryNames); selectedKeyAndCategory.y = categoryIndex; var category = currentSchema.categories[categoryIndex]; if (category.keys.Length == 0) { return("This category is empty"); } // KEYS var locKeyIndex = selectedKeyAndCategory.x; if (locKeyIndex < 0 || locKeyIndex >= category.keys.Length) { locKeyIndex = 0; } var keysRect = new Rect(rect) { x = rect.x + INDENTATION, y = rect.y + LINE_HEIGHT * 2, height = LINE_HEIGHT, width = rect.width - INDENTATION }; locKeyIndex = EditorGUI.Popup(keysRect, "Key", locKeyIndex, category.keys); selectedKeyAndCategory.x = locKeyIndex; var selectedLocKey = category.keys[locKeyIndex]; var savedLocKey = keyName.stringValue; var crc = CrcUtils.GetCrc( category.name, selectedLocKey); if (localisationKey.intValue != crc) { keyName.stringValue = selectedLocKey; categoryName.stringValue = category.name; localisationKey.intValue = CrcUtils.GetCrc( categoryName.stringValue, keyName.stringValue); savedLocKey = selectedLocKey; } if (string.IsNullOrEmpty(savedLocKey)) { GUILayout.Label("< NONE >", EditorStyles.boldLabel); } else { var style = new GUIStyle(EditorStyles.boldLabel); if (!keyLookup.IsValid) { return(string.Format("Key contents ({0}/{1}:{2}) not found in the schema - please set it to a new value", categoryName.stringValue, keyName.stringValue, localisationKey.intValue)); style.normal.textColor = Color.red; } GUILayout.Label(string.Format("{0}/{1} ({2}) {3}", categoryName.stringValue, keyName.stringValue, localisationKey.intValue, savedLocKey != selectedLocKey ? "*" : string.Empty ), style); } return(null); }
private void DrawLocalisationContents(LocalisationKeySchema currentSchema) { GUILayout.Label("Localisation texts", EditorStyles.boldLabel); showCRC = EditorGUILayout.Toggle("Show CRC values", showCRC); EditorGUILayout.LabelField("CRC version: ", crcEncodingVersion.intValue.ToString(), EditorStyles.helpBox); if (currentSchema.categories.Length > contentToggles.Length) { contentToggles = new bool[currentSchema.categories.Length]; } keyMap.Clear(); for (var i = 0; i < localisationKeys.arraySize; i++) { // mapping of locKey to its index in the keysArray (i.e. Array.IndexOf lookup-table) keyMap.Add(localisationKeys.GetArrayElementAtIndex(i).intValue, i); } var updateKeyEncoding = (crcEncodingVersion.intValue >= 0 && crcEncodingVersion.intValue != CrcUtils.KEY_CRC_ENCODING_VERSION); for (var i = 0; i < currentSchema.categories.Length; i++) { var category = currentSchema.categories[i]; contentToggles[i] = EditorGUILayout.Foldout(contentToggles[i], category.name); if (contentToggles[i] || updateKeyEncoding) { EditorGUI.indentLevel++; for (var j = 0; j < category.keys.Length; j++) { var locKeyCRC = CrcUtils.GetCrcWithEncodingVersion(category.name, category.keys[j], crcEncodingVersion.intValue); if (contentToggles[i]) { if (!showCRC) { EditorGUILayout.BeginHorizontal(); } EditorGUILayout.LabelField( string.Format("{0} {1}", category.keys[j], showCRC ? "(" + locKeyCRC + ")" : string.Empty), EditorStyles.boldLabel, GUILayout.MaxWidth(showCRC ? 200f : 140f)); } var currentValue = string.Empty; SerializedProperty currentValueProperty = null; if (keyMap.ContainsKey(locKeyCRC)) { var currentArrayIndex = keyMap[locKeyCRC]; if (updateKeyEncoding) { keyMap.Remove(locKeyCRC); locKeyCRC = CrcUtils.GetCrc(category.name, category.keys[j]); localisationKeys.GetArrayElementAtIndex(currentArrayIndex).intValue = locKeyCRC; keyMap.Add(locKeyCRC, currentArrayIndex); } currentValueProperty = localisationValues.GetArrayElementAtIndex(currentArrayIndex); currentValue = currentValueProperty.stringValue; } if (contentToggles[i]) { var newValue = EditorGUILayout.DelayedTextField(currentValue); if (!showCRC) { EditorGUILayout.EndHorizontal(); } if (newValue != currentValue) { if (currentValueProperty != null) { currentValueProperty.stringValue = newValue; } else { localisationKeys.arraySize++; localisationValues.arraySize++; localisationKeys.GetArrayElementAtIndex(localisationKeys.arraySize - 1).intValue = locKeyCRC; localisationValues.GetArrayElementAtIndex(localisationValues.arraySize - 1).stringValue = newValue; } } } } EditorGUI.indentLevel--; } } if (updateKeyEncoding) { crcEncodingVersion.intValue = CrcUtils.KEY_CRC_ENCODING_VERSION; Debug.Log(string.Format("Localisation table '{0}' updated key CRC encoding to latest version: {1}", targetTable.name, crcEncodingVersion.intValue)); } serializedObject.ApplyModifiedProperties(); }