/// <summary> /// Updates every localization .CSV file associated with this /// .yarnproject file. /// </summary> /// <remarks> /// This method updates each localization file by performing the /// following operations: /// /// - Inserts new entries if they're present in the base /// localization and not in the translated localization /// /// - Removes entries if they're present in the translated /// localization and not in the base localization /// /// - Detects if a line in the base localization has changed its /// Lock value from when the translated localization was created, /// and update its Comment /// </remarks> /// <param name="serializedObject">A serialized object that /// represents a <see cref="YarnProjectImporter"/>.</param> internal static void UpdateLocalizationCSVs(YarnProjectImporter yarnProjectImporter) { if (yarnProjectImporter.CanGenerateStringsTable == false) { Debug.LogError($"Can't update localization CSVs for Yarn Project \"{yarnProjectImporter.name}\" because not every line has a tag."); return; } var baseLocalizationStrings = yarnProjectImporter.GenerateStringsTable(); var localizations = yarnProjectImporter.languagesToSourceAssets; var modifiedFiles = new List <TextAsset>(); try { AssetDatabase.StartAssetEditing(); foreach (var loc in localizations) { if (loc.stringsFile == null) { Debug.LogWarning($"Can't update localization for {loc.languageID} because it doesn't have a strings file.", yarnProjectImporter); continue; } var fileWasChanged = UpdateLocalizationFile(baseLocalizationStrings, loc.languageID, loc.stringsFile); if (fileWasChanged) { modifiedFiles.Add(loc.stringsFile); } } if (modifiedFiles.Count > 0) { Debug.Log($"Updated the following files: {string.Join(", ", modifiedFiles.Select(f => AssetDatabase.GetAssetPath(f)))}"); } else { Debug.Log($"No files needed updating."); } } finally { AssetDatabase.StopAssetEditing(); } }
internal static void UpdateAssetAddresses(YarnProjectImporter importer) { #if USE_ADDRESSABLES var lineIDs = importer.GenerateStringsTable().Select(s => s.ID); // Get a map of language IDs to (lineID, asset path) pairs var languageToAssets = importer // Get the languages-to-source-assets map .languagesToSourceAssets // Get the asset folder for them .Select(l => new { l.languageID, l.assetsFolder }) // Only consider those that have an asset folder .Where(f => f.assetsFolder != null) // Get the path for the asset folder .Select(f => new { f.languageID, path = AssetDatabase.GetAssetPath(f.assetsFolder) }) // Use that to get the assets inside these folders .Select(f => new { f.languageID, assetPaths = FindAssetPathsForLineIDs(lineIDs, f.path) }); var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings; foreach (var languageToAsset in languageToAssets) { var assets = languageToAsset.assetPaths .Select(pair => new { LineID = pair.Key, GUID = AssetDatabase.AssetPathToGUID(pair.Value) }); foreach (var asset in assets) { // Find the existing entry for this asset, if it has // one. AddressableAssetEntry entry = addressableAssetSettings.FindAssetEntry(asset.GUID); if (entry == null) { // This asset didn't have an entry. Create one in // the default group. entry = addressableAssetSettings.CreateOrMoveEntry(asset.GUID, addressableAssetSettings.DefaultGroup); } // Update the entry's address. entry.SetAddress(Localization.GetAddressForLine(asset.LineID, languageToAsset.languageID)); } } #else throw new System.NotSupportedException($"A method that requires the Addressable Assets package was called, but USE_ADDRESSABLES was not defined. Please either install Addressable Assets, or if you have already, add it to this project's compiler definitions."); #endif }
/// <summary> /// Writes a .csv file to disk at the path indicated by <paramref /// name="destination"/>, containing all of the lines found in the /// scripts referred to by <paramref name="yarnProjectImporter"/>. /// </summary> /// <remarks> /// The file generated is in a format ready to be added to the <see /// cref="YarnProjectImporter.languagesToSourceAssets"/> list. /// </remarks> /// <param name="yarnProjectImporter">The YarnProjectImporter to /// extract strings from.</param> /// <param name="destination">The path to write the file /// to.</param> /// <returns><see langword="true"/> if the file was written /// successfully, <see langword="false"/> otherwise.</returns> /// <exception cref="CsvHelper.CsvHelperException">Thrown when an /// error is encountered when generating the CSV data.</exception> /// <exception cref="IOException">Thrown when an error is /// encountered when writing the data to disk.</exception> internal static bool WriteStringsFile(string destination, YarnProjectImporter yarnProjectImporter) { // Perform a strings-only compilation to get a full strings // table, and generate the CSV. var stringTable = yarnProjectImporter.GenerateStringsTable(); // If there was an error, bail out here if (stringTable == null) { return(false); } // Convert the string tables to CSV... var outputCSV = StringTableEntry.CreateCSV(stringTable); // ...and write it to disk. File.WriteAllText(destination, outputCSV); return(true); }