LocalizationEditorSettings.CreateStringTableCollection() Without Placing Tables in a Directory

I’m working on a dialogue system that relies on the Localization Tools to store text and translations of that text. I would like to make my own asset type for each dialogue conversation that would store it’s own StringTableCollection and StringTables along with dialogue node information (a custom ScriptableObject). This would be created with a custom ScriptedImporter (all this is for keeping assets organized).

This is my first time making a scripted importer so I may not know all the limitations but I believe I should be able to add an instance of the StringTableCollection and the tables it references to the main asset using the Scripted Importer Api, but right now when calling LocalizationEditorSettings.CreateStringTableCollection() you have to pass a directory path where the tables will be created. Would a feature be possible to create the instances of the table collection and tables without creating the .asset file? I tried replicating the LocalizationEditorSettings.CreateStringTableCollection() method without creating the .asset files but there are some internal properties I would need to set in order to do it correctly.

1 Like

Hmm I’m not sure it would be possible to not include any as we find out tables by searching for this asset.
Do you plan to use your own asset type in the player or just the editor? For player you could try this https://discussions.unity.com/t/815428
One thing that may work is of you create an empty collection asset by passing in no locales and then call AddTable with your tables.If you want to use your own asset type then you may have more luck following the way we do it for CSV and XLIFF.
You could also try creating a StringTableCollection with Scriptable Object CreateInstance.

How would I go about assigning a SharedTableData to a StringTableCollection created through ScriptableObject.CreateInstance(). Is it necessary to have ShareTableData? For now I’m able to generate a StringTableCollection as a sub asset of my custom asset(via custom ScriptedImporter) but when inspecting it I get an EditorGUI HelpBox saying “This collection is missing it’s Shared Table Data”. If I’m not able to create the StringTableCollection and assign it’s shared table I’ll look into storing dialogue directly in a csv instead of in StringTables.

What do you want to do with the collection once it’s generated? Do you want to edit it in the table editor or is it just so it can be exported to the player? If it’s just for player use then you may be better making a build step to generate temporary files during build.
The shared table data is important.

I would like the collection(along with it’s tables) to be a sub asset of my main .dialogue asset. For reference, like how the Input System has it’s own .inputactions asset that generates all the associated input actions through a ScriptedImporter.

For the sake of tidiness I’d like to do something similar and keep the string tables required for a specific dialogue interaction bound to my custom .dialogue asset. Before this I just create the StringTableCollection manually and link it to my dialogue asset, this is fine but if the project grows with multiple dialogue interactions, assets might get confusing to find.

How I plan on editing the table is with a custom graph/node editor window. When creating a node, it will create a table entry and fill the entry with whatever I type in it. The nodes will only save the table entry’s Key Id to a ScriptableObject. This ScriptableObject will be accessed at runtime and have a LocalizedStringTable that a MonoBehaviour would access to load and display the text.

I managed to get it to work but the code is kind of janky and causes an editor error that requires it to restart. It does accomplish what I want but the errors are not ideal. I delete the asset file of the collection and tables after adding the objects to the asset.

using UnityEditor.AssetImporters;
using UnityEngine;
using System.IO;
using System;
using UnityEditor.Localization;

namespace PhantasmicGames.Dialogue.Editor
{
    [ScriptedImporter(Version, Dialogue.Extension)]
    public class DialogueImporter : ScriptedImporter
    {
        private const int Version = 1;

        public override void OnImportAsset(AssetImportContext ctx)
        {
            string text;
            try
            {
                text = File.ReadAllText(ctx.assetPath);
            }
            catch (Exception exception)
            {
                ctx.LogImportError($"Could not read file '{ctx.assetPath}' ({exception})");
                return;
            }

            var asset = ScriptableObject.CreateInstance<Dialogue>();

            asset.name = Path.GetFileNameWithoutExtension(ctx.assetPath);

            ctx.AddObjectToAsset("<root>", asset);
            ctx.SetMainObject(asset);

            string path = ctx.assetPath.Replace(Path.GetFileName(ctx.assetPath), string.Empty);

            StringTableCollection collection = LocalizationEditorSettings.CreateStringTableCollection(asset.name, path);
            ctx.AddObjectToAsset("collection", collection);
            ctx.AddObjectToAsset("share data", collection.SharedData);

            foreach (var table in collection.StringTables)
            {
                ctx.AddObjectToAsset(table.name, table);
            }

            AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(collection));
            AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(collection.SharedData));
            foreach (var table in collection.StringTables)
            {
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(table));
            }
        }

        [MenuItem("Assets/Create/Dialogue")]
        public static void CreateDialogueAsset()
        {
            ProjectWindowUtil.CreateAssetWithContent("New Dialogue." + Dialogue.Extension, "{}");
        }
    }
}

This is what it looks like in the project window.

My goal is to package all the dependencies for a dialogue interaction in one asset for better project management like the picture shows. The collection seems to be fine as it can still be found and edited in the Localization Tables editor window. This is what makes me think that a version of the LocalizationEditorSettings.CreateStringTableCollection() method, that does not create the assets in the project folder, would benefit custom assets.

Ok ill see if we can better support this in the future.

1 Like

Did anything change about this since last comment?
We would like to do something very simillar

No, not at the moment. There’s limitations with the above suggestion. When the assets are sub assets they are all a single asset which means that we have to load the whole asset each time, we cant just load a single language anymore. I would recommend putting each table collection into its own folder instead.