433 lines
18 KiB
C#
433 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEditor;
|
|
using UnityEditor.Localization;
|
|
using UnityEditor.Localization.Plugins.Google;
|
|
using UnityEditor.Localization.Plugins.Google.Columns;
|
|
using UnityEditor.Localization.Reporting;
|
|
using UnityEngine;
|
|
using UnityEngine.Localization;
|
|
using UnityEngine.Localization.Metadata;
|
|
using UnityEngine.Localization.Tables;
|
|
|
|
#region setup-extension
|
|
|
|
public static class SetupExtensionSample
|
|
{
|
|
[MenuItem("CONTEXT/StringTableCollection/Add Configured Google Sheet Extension")]
|
|
public static void AddAndConfigureExtension(MenuCommand command)
|
|
{
|
|
var collection = command.context as StringTableCollection;
|
|
|
|
// Get or add a new GoogleSheetsExtension.
|
|
var googleExtension = collection.Extensions.FirstOrDefault(e => e is GoogleSheetsExtension) as GoogleSheetsExtension;
|
|
if (googleExtension == null)
|
|
{
|
|
googleExtension = new GoogleSheetsExtension();
|
|
collection.AddExtension(googleExtension);
|
|
}
|
|
|
|
// Clear old data.
|
|
googleExtension.Columns.Clear();
|
|
|
|
// We need configure what each column will contain in the sheet
|
|
var columnMappings = new List<SheetColumn>
|
|
{
|
|
// Column A will contain the Key
|
|
new KeyColumn { Column = "A" },
|
|
|
|
// Column B will contain any shared comments. These are Comment Metadata in the Shared category.
|
|
new KeyCommentColumn { Column = "B" },
|
|
|
|
// Column C will contain the English Locale and any comments that are just for this Locale.
|
|
new LocaleColumn { Column = "C", LocaleIdentifier = "en", IncludeComments = true },
|
|
};
|
|
|
|
// Assign the columns to the extension
|
|
googleExtension.Columns.AddRange(columnMappings);
|
|
|
|
// Assign our Google Sheets service asset
|
|
const string pathToYourAsset = "Assets/Google Sheets Service.asset"; //The path to your SheetsServiceProvider asset. See docs for further info.
|
|
var sheetsServiceProvider = AssetDatabase.LoadAssetAtPath<SheetsServiceProvider>(pathToYourAsset);
|
|
googleExtension.SheetsServiceProvider = sheetsServiceProvider;
|
|
|
|
googleExtension.SpreadsheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.
|
|
googleExtension.SheetId = 123456; // This is the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.
|
|
|
|
// Mark the collection dirty so that the changes are saved
|
|
EditorUtility.SetDirty(collection);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region locale-metadata-column
|
|
|
|
[Serializable]
|
|
[DisplayName("Custom Data")]
|
|
[Metadata(AllowedTypes = MetadataType.StringTableEntry)]
|
|
public class MyCustomDataMetadata : IMetadata
|
|
{
|
|
public string someValue;
|
|
public string someNoteValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// LocaleMetadataColumn is a version of SheetColumn only used for handling Metadata.
|
|
/// This can now be added to the Column Mappings for any Push or Pull request.
|
|
/// </summary>
|
|
public class MyCustomColumn : LocaleMetadataColumn<MyCustomDataMetadata>
|
|
{
|
|
public override PushFields PushFields => PushFields.ValueAndNote; // For our example we use both value and note.
|
|
|
|
public override void PullMetadata(StringTableEntry entry, MyCustomDataMetadata metadata, string cellValue, string cellNote)
|
|
{
|
|
// Metadata will be null if the entry does not already contain any.
|
|
if (metadata == null)
|
|
{
|
|
metadata = new MyCustomDataMetadata();
|
|
entry.AddMetadata(metadata);
|
|
}
|
|
|
|
metadata.someValue = cellValue;
|
|
metadata.someNoteValue = cellNote;
|
|
}
|
|
|
|
public override void PushHeader(StringTableCollection collection, out string header, out string headerNote)
|
|
{
|
|
// The title of the Google Sheet column
|
|
header = "My Custom Data";
|
|
headerNote = null;
|
|
}
|
|
|
|
public override void PushMetadata(MyCustomDataMetadata metadata, out string value, out string note)
|
|
{
|
|
// Metadata will never be null as this is only called if the entry contains a metadata entry.
|
|
value = metadata.someValue;
|
|
note = metadata.someNoteValue;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region smart-string-column
|
|
|
|
public class SmartStringColumn : LocaleMetadataColumn<SmartFormatTag>
|
|
{
|
|
public override PushFields PushFields => PushFields.Value;
|
|
|
|
public override void PullMetadata(StringTableEntry entry, SmartFormatTag metadata, string cellValue, string cellNote)
|
|
{
|
|
entry.IsSmart = !string.IsNullOrEmpty(cellValue);
|
|
}
|
|
|
|
public override void PushHeader(StringTableCollection collection, out string header, out string headerNote)
|
|
{
|
|
header = $"{LocaleIdentifier.ToString()} - Is Smart String";
|
|
headerNote = null;
|
|
}
|
|
|
|
public override void PushMetadata(SmartFormatTag metadata, out string value, out string note)
|
|
{
|
|
value = "x"; // We mark here with an x but it could be anything.
|
|
note = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region global-smart-string-column
|
|
|
|
[Serializable]
|
|
public class GlobalSmartStringColumn : SheetColumn
|
|
{
|
|
public override PushFields PushFields => PushFields.Value;
|
|
|
|
StringTableCollection m_TableCollection;
|
|
|
|
public override void PullBegin(StringTableCollection collection)
|
|
{
|
|
m_TableCollection = collection;
|
|
}
|
|
|
|
public override void PullCellData(SharedTableData.SharedTableEntry keyEntry, string cellValue, string cellNote)
|
|
{
|
|
bool enableSmartString = !string.IsNullOrEmpty(cellValue);
|
|
|
|
// Go through all the entries
|
|
foreach (var table in m_TableCollection.StringTables)
|
|
{
|
|
var entry = table.GetEntry(keyEntry.Id);
|
|
if (entry != null)
|
|
entry.IsSmart = enableSmartString;
|
|
}
|
|
}
|
|
|
|
public override void PushBegin(StringTableCollection collection)
|
|
{
|
|
m_TableCollection = collection;
|
|
}
|
|
|
|
public override void PushCellData(SharedTableData.SharedTableEntry keyEntry, IList<StringTableEntry> tableEntries, out string value, out string note)
|
|
{
|
|
// Use the first table as our source of truth
|
|
var entry = m_TableCollection.StringTables[0].GetEntry(keyEntry.Id);
|
|
value = entry != null && entry.IsSmart ? "x" : string.Empty;
|
|
note = null;
|
|
}
|
|
|
|
public override void PushHeader(StringTableCollection collection, out string header, out string headerNote)
|
|
{
|
|
header = "Smart String";
|
|
headerNote = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// These examples show various ways to sync a String Table Collection with Google Sheets.
|
|
/// These examples are illustrative and will not work as they are without correct Google Sheets credentials and String Table data.
|
|
/// </summary>
|
|
public class GoogleSheetsExamples
|
|
{
|
|
static SheetsServiceProvider GetServiceProvider()
|
|
{
|
|
#region sheets-service-provider
|
|
|
|
// The Sheets service provider performs the authentication and keeps track of the
|
|
// authentication tokens so that we do not need to authenticate each time.
|
|
// It is recommended to have a SheetsServiceProvider asset pre-configured for
|
|
// use however in this example we will create a new one.
|
|
var sheetServiceProvider = ScriptableObject.CreateInstance<SheetsServiceProvider>();
|
|
|
|
// OAuth is required when making changes. See the docs for info setting up OAuth credentials.
|
|
sheetServiceProvider.SetOAuthCredentials("some-client-id", "some-client-secret");
|
|
return sheetServiceProvider;
|
|
#endregion
|
|
}
|
|
|
|
#region push-collection-english
|
|
|
|
[MenuItem("Localization/Google Sheets/Push English")]
|
|
public static void PushEnglish()
|
|
{
|
|
// Setup the connection to Google. You will need a preconfigured SheetsServiceProvider asset.
|
|
var sheetServiceProvider = AssetDatabase.LoadAssetAtPath<SheetsServiceProvider>("Assets/Sheets Service Provider.asset");
|
|
var googleSheets = new GoogleSheets(sheetServiceProvider);
|
|
googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.
|
|
|
|
// Prepare the data we want to push.
|
|
// You should provide your String Table Collection name here
|
|
var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
|
|
|
|
// We need configure what each column will contain in the sheet
|
|
var columnMappings = new SheetColumn[]
|
|
{
|
|
// Column A will contain the Key
|
|
new KeyColumn { Column = "A" },
|
|
|
|
// Column B will contain any shared comments. These are Comment Metadata in the Shared category.
|
|
new KeyCommentColumn { Column = "B" },
|
|
|
|
// Column C will contain the English Locale and any comments that are just for this Locale.
|
|
new LocaleColumn { Column = "C", LocaleIdentifier = "en", IncludeComments = true },
|
|
};
|
|
|
|
int mySheetId = 123456; // This it the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.
|
|
|
|
// Now send the update.
|
|
googleSheets.PushStringTableCollection(mySheetId, tableCollection, columnMappings);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region pull-collection-english
|
|
|
|
[MenuItem("Localization/Google Sheets/Pull English")]
|
|
public static void PullEnglish()
|
|
{
|
|
// Setup the connection to Google. You will need a preconfigured SheetsServiceProvider asset.
|
|
var sheetServiceProvider = AssetDatabase.LoadAssetAtPath<SheetsServiceProvider>("Assets/Sheets Service Provider.asset");
|
|
var googleSheets = new GoogleSheets(sheetServiceProvider);
|
|
googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.
|
|
|
|
// You should provide your String Table Collection name here
|
|
var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
|
|
|
|
// We need configure what each column contains in the sheet
|
|
var columnMappings = new SheetColumn[]
|
|
{
|
|
// Column A contains the Key
|
|
new KeyColumn { Column = "A" },
|
|
|
|
// Column B contains any shared comments. These are Comment Metadata in the Shared category.
|
|
new KeyCommentColumn { Column = "B" },
|
|
|
|
// Column C contains the English Locale and any comments that are just for this Locale.
|
|
new LocaleColumn { Column = "C", LocaleIdentifier = "en", IncludeComments = true },
|
|
};
|
|
|
|
int mySheetId = 123456; // This it the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.
|
|
googleSheets.PullIntoStringTableCollection(mySheetId, tableCollection, columnMappings);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region push-project-locales
|
|
|
|
[MenuItem("Localization/Google Sheets/Push Project Locales")]
|
|
public static void PushProjectLocales()
|
|
{
|
|
// Setup the connection to Google. You will need a preconfigured SheetsServiceProvider asset.
|
|
var sheetServiceProvider = AssetDatabase.LoadAssetAtPath<SheetsServiceProvider>("Assets/Sheets Service Provider.asset");
|
|
var googleSheets = new GoogleSheets(sheetServiceProvider);
|
|
googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.
|
|
|
|
// Prepare the data we want to push.
|
|
// You should provide your String Table Collection name here
|
|
var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
|
|
|
|
// CreateDefaultMapping will create a KeyColumn and a LocaleColumn for each Locale in the project.
|
|
var columnMappings = ColumnMapping.CreateDefaultMapping();
|
|
int mySheetId = 123456; // This is the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.
|
|
|
|
// Now send the update. We can pass in an optional ProgressBarReporter so that we can see updates in the Editor.
|
|
googleSheets.PushStringTableCollection(mySheetId, tableCollection, columnMappings, new ProgressBarReporter());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region pull-project-locales
|
|
|
|
[MenuItem("Localization/Google Sheets/Pull Project Locales")]
|
|
public static void PullProjectLocales()
|
|
{
|
|
// Setup the connection to Google. You will need a preconfigured SheetsServiceProvider asset.
|
|
var sheetServiceProvider = AssetDatabase.LoadAssetAtPath<SheetsServiceProvider>("Assets/Sheets Service Provider.asset");
|
|
var googleSheets = new GoogleSheets(sheetServiceProvider);
|
|
googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.
|
|
|
|
// You should provide your String Table Collection name here
|
|
var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
|
|
|
|
// CreateDefaultMapping will create a KeyColumn and a LocaleColumn for each Locale in the project.
|
|
// This assumes that the table was created and pushed to using the same column mappings.
|
|
var columnMappings = ColumnMapping.CreateDefaultMapping();
|
|
int mySheetId = 123456; // This it the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.
|
|
|
|
// Now pull.
|
|
// removeMissingEntries will remove any Keys that we have in the String Table Collection that do not exist in the Pull update.
|
|
// reporter is an optional reporter that can be used to povide feedback in the editor during the Pull.
|
|
googleSheets.PullIntoStringTableCollection(mySheetId, tableCollection, columnMappings, removeMissingEntries: true, reporter: new ProgressBarReporter());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region push-with-extension
|
|
|
|
[MenuItem("Localization/Google Sheets/Push With Google Extension")]
|
|
public static void PushWithExtension()
|
|
{
|
|
// You should provide your String Table Collection name here
|
|
var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
|
|
var googleExtension = tableCollection.Extensions.FirstOrDefault(e => e is GoogleSheetsExtension) as GoogleSheetsExtension;
|
|
if (googleExtension == null)
|
|
{
|
|
Debug.LogError($"String Table Collection {tableCollection.TableCollectionName} Does not contain a Google Sheets Extension.");
|
|
return;
|
|
}
|
|
|
|
PushExtension(googleExtension);
|
|
}
|
|
|
|
static void PushExtension(GoogleSheetsExtension googleExtension)
|
|
{
|
|
// Setup the connection to Google
|
|
var googleSheets = new GoogleSheets(googleExtension.SheetsServiceProvider);
|
|
googleSheets.SpreadSheetId = googleExtension.SpreadsheetId;
|
|
|
|
// Now send the update. We can pass in an optional ProgressBarReporter so that we can updates in the Editor.
|
|
googleSheets.PushStringTableCollection(googleExtension.SheetId, googleExtension.TargetCollection as StringTableCollection, googleExtension.Columns, new ProgressBarReporter());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region pull-with-extension
|
|
|
|
[MenuItem("Localization/Google Sheets/Pull With Google Extension")]
|
|
public static void PullWithExtension()
|
|
{
|
|
// You should provide your String Table Collection name here
|
|
var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
|
|
var googleExtension = tableCollection.Extensions.FirstOrDefault(e => e is GoogleSheetsExtension) as GoogleSheetsExtension;
|
|
if (googleExtension == null)
|
|
{
|
|
Debug.LogError($"String Table Collection {tableCollection.TableCollectionName} Does not contain a Google Sheets Extension.");
|
|
return;
|
|
}
|
|
|
|
PullExtension(googleExtension);
|
|
}
|
|
|
|
static void PullExtension(GoogleSheetsExtension googleExtension)
|
|
{
|
|
// Setup the connection to Google
|
|
var googleSheets = new GoogleSheets(googleExtension.SheetsServiceProvider);
|
|
googleSheets.SpreadSheetId = googleExtension.SpreadsheetId;
|
|
|
|
// Now update the collection. We can pass in an optional ProgressBarReporter so that we can updates in the Editor.
|
|
googleSheets.PullIntoStringTableCollection(googleExtension.SheetId, googleExtension.TargetCollection as StringTableCollection, googleExtension.Columns, reporter: new ProgressBarReporter());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region push-all-extensions
|
|
|
|
[MenuItem("Localization/Google Sheets/Push All Google Sheets Extensions")]
|
|
public static void PushAllExtensions()
|
|
{
|
|
// Get every String Table Collection
|
|
var stringTableCollections = LocalizationEditorSettings.GetStringTableCollections();
|
|
|
|
foreach (var collection in stringTableCollections)
|
|
{
|
|
// Its possible a String Table Collection may have more than one GoogleSheetsExtension.
|
|
// For example if each Locale we pushed/pulled from a different sheet.
|
|
foreach (var extension in collection.Extensions)
|
|
{
|
|
if (extension is GoogleSheetsExtension googleExtension)
|
|
{
|
|
PushExtension(googleExtension);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region pull-all-extensions
|
|
|
|
[MenuItem("Localization/Google Sheets/Pull All Google Sheets Extensions")]
|
|
public static void PullAllExtensions()
|
|
{
|
|
// Get every String Table Collection
|
|
var stringTableCollections = LocalizationEditorSettings.GetStringTableCollections();
|
|
|
|
foreach (var collection in stringTableCollections)
|
|
{
|
|
// Its possible a String Table Collection may have more than one GoogleSheetsExtension.
|
|
// For example if each Locale we pushed/pulled from a different sheet.
|
|
foreach (var extension in collection.Extensions)
|
|
{
|
|
if (extension is GoogleSheetsExtension googleExtension)
|
|
{
|
|
PullExtension(googleExtension);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|