Forum rules - please read before posting.

How to translate save game labels

I have my game set up so it saves my custom scene name labels as well as the time and date, but I want these to be translatable too. I have my custom handler set like this:

using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
using SceneM = UnityEngine.SceneManagement.SceneManager;

namespace AC
{
    public class CustomSaveFileHandler_Timestamped : SaveFileHandler_SystemFile
    {
        private const string LogPrefix = "[CustomSaveFileHandler_Timestamped]";

        public override void Save(SaveFile saveFile, string dataString, Action<bool> callback)
        {
            if (saveFile == null)
            {
                ACDebug.LogWarning($"{LogPrefix} Save called with null SaveFile.");
                base.Save(saveFile, dataString, callback);
                return;
            }

            string rawScene = SceneM.GetActiveScene().name;

            int lang = GetCurrentLanguageIndex_Robust();
            ACDebug.Log($"{LogPrefix} Language index at save-time = {lang}");

            string friendlyScene = GetFriendlySceneName(rawScene, lang);

            string timeStamp = DateTime.Now.ToString("dd/MM/yyyy HH:mm");
            saveFile.label = $"{friendlyScene}\n[{timeStamp}]";

            ACDebug.Log($"{LogPrefix} Saving saveID {saveFile.saveID} with label:\n\"{saveFile.label}\"");

            base.Save(saveFile, dataString, success =>
            {
                ACDebug.Log($"{LogPrefix} Save finished for ID {saveFile.saveID} (success={success})");
                callback?.Invoke(success);
            });
        }

        // --------------------------------------------------------------------
        // LANGUAGE DETECTION (AC 1.85.5 safe + robust fallbacks)
        // Your setup (per screenshot):
        // 0 = English (Original)
        // 1 = German
        // 2 = Spanish
        // --------------------------------------------------------------------

        private int GetCurrentLanguageIndex_Robust()
        {
            // 1) Preferred: static Options.GetLanguage()
            try
            {
                return Options.GetLanguage();
            }
            catch { /* ignore */ }

            // 2) Fallback: try instance KickStarter.options.GetLanguage() (some setups)
            try
            {
                if (KickStarter.options != null)
                {
                    MethodInfo mi = KickStarter.options.GetType().GetMethod("GetLanguage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                    if (mi != null && mi.ReturnType == typeof(int))
                    {
                        return (int)mi.Invoke(KickStarter.options, null);
                    }
                }
            }
            catch { /* ignore */ }

            // 3) Fallback: look for optionsData.language (common in AC)
            try
            {
                if (KickStarter.options != null)
                {
                    object optionsData = GetMemberValue(KickStarter.options, "optionsData");
                    if (optionsData != null)
                    {
                        object langObj = GetMemberValue(optionsData, "language");
                        if (langObj is int i) return i;
                    }
                }
            }
            catch { /* ignore */ }

            // 4) Fallback: look for language-ish fields on SpeechManager (names vary by version)
            try
            {
                if (KickStarter.speechManager != null)
                {
                    // Try a few likely member names without hardcoding AC version-specific APIs
                    string[] candidates = { "language", "currentLanguage", "selectedLanguage", "gameLanguage", "speechLanguage" };
                    foreach (string name in candidates)
                    {
                        object val = GetMemberValue(KickStarter.speechManager, name);
                        if (val is int i) return i;
                    }
                }
            }
            catch { /* ignore */ }

            // Default to original language
            return 0;
        }

        private object GetMemberValue(object obj, string memberName)
        {
            if (obj == null) return null;

            Type t = obj.GetType();

            // Property
            PropertyInfo pi = t.GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (pi != null) return pi.GetValue(obj, null);

            // Field
            FieldInfo fi = t.GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (fi != null) return fi.GetValue(obj);

            return null;
        }

        // --------------------------------------------------------------------
        // TRANSLATION
        // German first, then Spanish, else English (fallback)
        // --------------------------------------------------------------------

        private string GetFriendlySceneName(string raw, int lang)
        {
            if (lang == 1) return GetGermanSceneName(raw);   // German
            if (lang == 2) return GetSpanishSceneName(raw);  // Spanish
            return GetEnglishSceneName(raw);                 // English / fallback
        }

        private string GetEnglishSceneName(string raw)
        {
            switch (raw)
            {
                case "MeMeBedroom": return "The Bedroom";
                case "MeMeUpstairs": return "The Balcony";
                case "MeMeBasement": return "The Basement";
                default: return raw;
            }
        }

        private string GetSpanishSceneName(string raw)
        {
            switch (raw)
            {
                case "MeMeBedroom": return "El Dormitorio";
                case "MeMeUpstairs": return "El Balcón";
                case "MeMeBasement": return "El Sótano";
                default: return raw;
            }
        }

        private string GetGermanSceneName(string raw)
        {
            switch (raw)
            {
                case "MeMeBedroom": return "Das Schlafzimmer";
                case "MeMeUpstairs": return "Der Balkon";
                case "MeMeBasement": return "Der Keller";
                default: return raw;
            }
        }
    }
}

Which works, BUT doesn't work if I change the langauge in game, any ideas how to fix this? THANKS

Comments

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.