Adventure Creator Wikia
Advertisement

This script updates a Unity UI-based menu's fonts based on the current language. It works by replacing the font field in all-found Text components when the menu is turned on, or when the language is changed.

To use it:

  1. Create a new C# file named DynamicFontLanguage.cs, and paste in the code below
  2. Attach the new Dynamic Font Language component to the root of your Unity UI menu prefab
  3. Assign a default Font in the Inspector, then create as many instances of the "Per Language Fonts" array as you have different fonts. For each, assign both a font, and the language index (as listed in the Speech Manager) it should display for.

DynamicFontLanguage.cs:

	using UnityEngine;
	using UnityEngine.UI;
	using AC;

	public class DynamicFontLanguage : MonoBehaviour
	{

		[SerializeField] private Font defaultFont;
		[SerializeField] private PerLanguageFont[] perLanguageFonts = new PerLanguageFont[0];
		private Text[] texts;

		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)
		{
			OnChangeLanguage (Options.GetLanguage ());
		}

		private void OnChangeLanguage (int languageIndex)
		{
			Font newFont = defaultFont;
			foreach (PerLanguageFont perLanguageFont in perLanguageFonts)
			{
				if (languageIndex == perLanguageFont.languageIndex && perLanguageFont.font)
				{
					newFont = perLanguageFont.font;
					break;
				}
			}

			if (newFont)
			{
				if (texts == null)
				{
					texts = GetComponentsInChildren <Text>();
				}

				foreach (Text text in texts)
				{
					text.font = newFont;
				}
			}
		}


		[System.Serializable]
		private class PerLanguageFont
		{

			public int languageIndex;
			public Font font;

		}

	}

Below addition by Jeremy Fryc (Dexter Team Games):

The above code works for standard Unity fonts. However, you may want to use TMP (TextMeshPro) for your Unity UI menus. In fact, this is a good idea. So, below is an updated version of the script that makes use of TMP. It also has an additional change that may be useful; There is now a public method UpdateFonts ().

Why is this public method useful? Sometimes, you have a Unity UI object that contains text, but it's disabled by default. If you change the language, then enter the menu with the disabled object, and then enable this object, it will not respect the font change (which only occurred when the UnityUI prefab was enabled in the Hierarchy). To remedy this, if you call this public method UpdateFonts () from a button event, it will dynamically change the font that corresponds to the font in the LanguageIndex. Neat!

In order to use the below script, follow all the directions as stated at the outset. Here is the script:

using UnityEngine;
using UnityEngine.UI;
using TMPro;
using AC;

public class DynamicFontLanguage : MonoBehaviour
{
    [SerializeField] private TMP_FontAsset defaultFont; 
    [SerializeField] private PerLanguageFont[] perLanguageFonts = new PerLanguageFont[0];
    private TextMeshProUGUI[] texts;

    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)
    {
        UpdateFonts(); 
    }

    private void OnChangeLanguage(int languageIndex)
    {
        UpdateFonts(); 
    }

    public void UpdateFonts()
    {
        int languageIndex = Options.GetLanguage(); 
        TMP_FontAsset newFont = defaultFont; 

        foreach (PerLanguageFont perLanguageFont in perLanguageFonts)
        {
            if (languageIndex == perLanguageFont.languageIndex && perLanguageFont.font)
            {
                newFont = perLanguageFont.font;
                break;
            }
        }

        if (newFont)
        {
            if (texts == null || texts.Length == 0)
            {
                texts = GetComponentsInChildren<TextMeshProUGUI>(true);
            }

            foreach (TextMeshProUGUI text in texts)
            {
                text.font = newFont;
            }
        }
    }

    [System.Serializable]
    private class PerLanguageFont
    {
        public int languageIndex;
        public TMP_FontAsset font;
    }
}
Advertisement