Forum rules - please read before posting.

Simplest way to change to a Chinese font when changing language to Chinese

Hi Chris. I'm considering translating my game into simplified Chinese, and am looking for the simplest way to change the font when the language is changed. Do you have any suggestions, please?
I'm using Unity 6 and AC 1.83. I only use the BradBun (Brady Bunch) font throughout, for both menus and subtitles. I don't use any TextMeshPro or UnityUI menus afaik, it's all AC menus and subtitles, so menu and subtitle text is showing up in the Text Export from Gather Text.
Thank you.

Comments

  • You'd need a custom script to swap the font used in your Menus. I'd recommend the use of Unity UI, as it's better-equipped to handle changes in content (i.e. font size) at runtime, but the act of changing the font is possible in all Source modes.

    A wiki page to handle UI-based menus can be found here. The script adapted to work with AC menus is as follows:

    using UnityEngine;
    using AC;
    
    public class DynamicFontLanguage : MonoBehaviour
    {
    
        [SerializeField] private Font defaultFont;
        [SerializeField] private PerLanguageFont[] perLanguageFonts = new PerLanguageFont[0];
    
        private void OnEnable ()
        {
            EventManager.OnChangeLanguage += OnChangeLanguage;
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
        }
    
        private void OnDisable ()
        {
            EventManager.OnChangeLanguage -= OnChangeLanguage;
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
        }
    
        private void OnMenuTurnOn (Menu _menu, bool isInstant)
        {
            UpdateAllMenus (Options.GetLanguage ());
        }
    
        private void OnChangeLanguage(int languageIndex)
        {
            UpdateAllMenus(languageIndex);
        }
    
        private void UpdateAllMenus (int languageIndex)
        {
            Font newFont = defaultFont;
            foreach (PerLanguageFont perLanguageFont in perLanguageFonts)
            {
                if (languageIndex == perLanguageFont.languageIndex && perLanguageFont.font)
                {
                    newFont = perLanguageFont.font;
                    break;
                }
            }
    
            if (newFont)
            {
                foreach (var menu in PlayerMenus.GetMenus())
                {
                    foreach (var element in menu.elements)
                    {
                        element.font = newFont;
                    }
                }
            }
        }
    
    
        [System.Serializable]
        private class PerLanguageFont
        {
    
            public int languageIndex;
            public Font font;
    
        }
    
    }
    
  • Thanks Chris. And is there a separate method to change the font for character dialogue/subtitles when changing language, or does this script cover that too?

  • It will change the font for all Menus, when the language is changed.

  • Thanks Chris. I was getting the error:
    "A script is calling 'PlayerMenus.GetMenus ()' before the Menus have been initialised - if this is a custom script, consider adjusting it's Script Execution Order."

    I tried changing the script execution order to 100 in the Project Settings, but I think that only worked when I had the script on an empty game object in the scene. Since I wanted the script to work in all scenes, I added it to the PersistentEngine, but the error returned.

    I got an LLM to make some changes, to delay the script. It works, I hope it's performant and not super unoptimised:

    using UnityEngine;
    using AC;
    using System.Collections;
    
    public class DynamicFontLanguage : MonoBehaviour
    {
        [SerializeField] private Font defaultFont;
        [SerializeField] private PerLanguageFont[] perLanguageFonts = new PerLanguageFont[0];
    
        private void OnEnable()
        {
            EventManager.OnChangeLanguage += OnChangeLanguage;
            EventManager.OnMenuTurnOn += OnMenuTurnOn;
            // Start a coroutine to update menus after initialization
            StartCoroutine(UpdateMenusAfterInitialization());
        }
    
        private void OnDisable()
        {
            EventManager.OnChangeLanguage -= OnChangeLanguage;
            EventManager.OnMenuTurnOn -= OnMenuTurnOn;
        }
    
        private void OnMenuTurnOn(Menu _menu, bool isInstant)
        {
            StartCoroutine(UpdateMenusAfterInitialization());
        }
    
        private void OnChangeLanguage(int languageIndex)
        {
            StartCoroutine(UpdateMenusAfterInitialization(languageIndex));
        }
    
        private IEnumerator UpdateMenusAfterInitialization(int languageIndex = -1)
        {
            // Wait until the end of the frame to ensure PlayerMenus is initialized
            yield return new WaitForEndOfFrame();
    
            // If no specific language index is provided, use the current language
            if (languageIndex == -1)
            {
                languageIndex = Options.GetLanguage();
            }
    
            UpdateAllMenus(languageIndex);
        }
    
        private void UpdateAllMenus(int languageIndex)
        {
            Font newFont = defaultFont;
            foreach (PerLanguageFont perLanguageFont in perLanguageFonts)
            {
                if (languageIndex == perLanguageFont.languageIndex && perLanguageFont.font)
                {
                    newFont = perLanguageFont.font;
                    break;
                }
            }
    
            if (newFont && PlayerMenus.GetMenus() != null)
            {
                foreach (var menu in PlayerMenus.GetMenus())
                {
                    foreach (var element in menu.elements)
                    {
                        element.font = newFont;
                    }
                }
            }
        }
    
        [System.Serializable]
        private class PerLanguageFont
        {
            public int languageIndex;
            public Font font;
        }
    }
    
  • Looks all right. It's running via events, not the Update loop, so it should be fine.

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.