snozbot / fungus

An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
MIT License
1.59k stars 291 forks source link

Feature Request: Localization quality of life changes #1022

Open TheEmbracedOne opened 2 years ago

TheEmbracedOne commented 2 years ago

Describe the solution you'd like

1) I'd like if there was a setting in Fungus that, when set, exports the localisation file into separate csv files, one per flowchart. 2) An easy way to refresh existing localisation files instead of having to re-export.

Is your feature request related to a problem? Please describe.

Use case: You have 5 flowcharts in a scene. One by one, you go and click "Export Localization File", and export each flowchart's localisation to its own CSV. Each CSV only has that one flowchart's localisation in it. You end up with 5 files. This would be useful for translation logistics, translators could work on separate files simultaneously.

This way, the old "one big CSV" approach is still available, but I think this might make sense for some projects.

Additionally, it'd be great if there was a way to easily refresh the existing Localization file:

See below for working code snippets.

TheEmbracedOne commented 2 years ago

I did some digging and it seems that the following change made it so that the "Export Localization File" now only exports from that one flowchart. One step closer to a solution that works better for me!

BEFORE:

        /// <summary>
        /// Builds a dictionary of localizable text items in the scene.
        /// </summary>
        protected Dictionary<string, TextItem> FindTextItems() {
            Dictionary<string, TextItem> textItems = new Dictionary<string, TextItem>();

            // Add localizable commands in same order as command list to make it
            // easier to localise / edit standard text.
            var flowcharts = GameObject.FindObjectsOfType<Flowchart>();
            for (int i = 0; i < flowcharts.Length; i++) {
                var flowchart = flowcharts[i];
                var blocks = flowchart.GetComponents<Block>();

                for (int j = 0; j < blocks.Length; j++) {
                    var block = blocks[j];
                    var commandList = block.CommandList;
                    for (int k = 0; k < commandList.Count; k++) {
                        var command = commandList[k];
                        ILocalizable localizable = command as ILocalizable;
                        if (localizable != null) {
                            TextItem textItem = new TextItem();
                            textItem.standardText = localizable.GetStandardText();
                            textItem.description = localizable.GetDescription();
                            textItems[localizable.GetStringId()] = textItem;
                        }
                    }
                }
            }

            // Add everything else that's localizable (including inactive objects)
            UnityEngine.Object[] objects = Resources.FindObjectsOfTypeAll(typeof(Component));
            for (int i = 0; i < objects.Length; i++) {
                var o = objects[i];
                ILocalizable localizable = o as ILocalizable;
                if (localizable != null) {
                    string stringId = localizable.GetStringId();
                    if (textItems.ContainsKey(stringId)) {
                        // Already added
                        continue;
                    }
                    TextItem textItem = new TextItem();
                    textItem.standardText = localizable.GetStandardText();
                    textItem.description = localizable.GetDescription();
                    textItems[stringId] = textItem;
                }
            }

            return textItems;
        }

AFTER:

        /// <summary>
        /// Builds a dictionary of localizable text items in the scene.
        /// </summary>
        protected Dictionary<string, TextItem> FindTextItems() {
            Dictionary<string, TextItem> textItems = new Dictionary<string, TextItem>();

            var flowchart = GetComponent<Flowchart>();
            var blocks = flowchart.GetComponents<Block>();

            for (int j = 0; j < blocks.Length; j++) {
                var commandList = blocks[j].CommandList;

                for (int k = 0; k < commandList.Count; k++) {
                    var command = commandList[k];
                    ILocalizable localizable = command as ILocalizable;

                    if (localizable != null) {
                        TextItem textItem = new TextItem();
                        textItem.standardText = localizable.GetStandardText();
                        textItem.description = localizable.GetDescription();
                        textItems[localizable.GetStringId()] = textItem;
                    }
                }
            }

            return textItems;
        }
TheEmbracedOne commented 2 years ago

I was able to add a new button to the LocalizationEditor called "Refresh Localization File" that takes the path of the localization file and just re-exports it, while renaming the old function to "ExportNewLocalizationFile" that works the exact same was as before.

A safety check would need to be implemented here that checks whether the localization file exists when clicking Refresh.

xDgvqPasqB

the code is a bit long so I used pastebin to showcase the original and the modified code below: original: https://pastebin.com/pPtBSMzs modified: https://pastebin.com/0k6MrGW6

Under the hood, this pretty much does the exact same as the regular export, ust takes the LocalizationFile property's path and exports it there without the "save as" window.

I have no idea if/how the latter works if you dont have the former change, use with caution ¯_(ツ)_/¯

TheEmbracedOne commented 2 years ago

updated this issue with more findings, formatting and reworded the original request