How do I change font of all texts in all scenes?

Hi,

I developed around 20 scenes and all are contains some texts.
Now I have new fonts that I want to apply to all texts.
I don’t want to go one by one and do it manually.
Is there any way to set it somewhere and all texts automatically use that font?

Please help…

Thanks in advance.

Late reply.

Here is a an editor window script I made to Find and Replace every UnityEngine.UI.Text fonts in open scene(s) with the option to include project prefabs. (Tested on Unity 5.6.0f3)

If you don’t specify a fond to find it will match them all.

Go to Utilities > Replace Font… to use it!

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class FontReplacer : EditorWindow
{
    private const string EditorPrefsKey = "Utilities.FontReplacer";
    private const string MenuItemName = "Utilities/Replace Fonts...";

    private Font _src;
    private Font _dest;
    private bool _includePrefabs;

    [MenuItem(MenuItemName)]
    public static void DisplayWindow()
    {
        var window = GetWindow<FontReplacer>(true, "Replace Fonts");
        var position = window.position;
        position.size = new Vector2(position.size.x, 151);
        position.center = new Rect(0f, 0f, Screen.currentResolution.width, Screen.currentResolution.height).center;
        window.position = position;
        window.Show();
    }

    public void OnEnable()
    {
        var path = EditorPrefs.GetString(EditorPrefsKey + ".src");
        if (path != string.Empty)
            _src = AssetDatabase.LoadAssetAtPath<Font>(path) ?? Resources.GetBuiltinResource<Font>(path);

        path = EditorPrefs.GetString(EditorPrefsKey + ".dest");
        if (path != string.Empty)
            _dest = AssetDatabase.LoadAssetAtPath<Font>(path) ?? Resources.GetBuiltinResource<Font>(path);

        _includePrefabs = EditorPrefs.GetBool(EditorPrefsKey + ".includePrefabs", false);
    }

    public void OnGUI()
    {
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PrefixLabel("Find:");
        _src = (Font)EditorGUILayout.ObjectField(_src, typeof(Font), false);

        EditorGUILayout.Space();
        EditorGUILayout.PrefixLabel("Replace with:");
        _dest = (Font)EditorGUILayout.ObjectField(_dest, typeof(Font), false);

        EditorGUILayout.Space();
        _includePrefabs = EditorGUILayout.ToggleLeft("Include Prefabs", _includePrefabs);
        if (EditorGUI.EndChangeCheck())
        {
            EditorPrefs.SetString(EditorPrefsKey + ".src", GetAssetPath(_src, "ttf"));
            EditorPrefs.SetString(EditorPrefsKey + ".dest", GetAssetPath(_dest, "ttf"));
            EditorPrefs.SetBool(EditorPrefsKey + ".includePrefabs", _includePrefabs);
        }
        
        GUI.color = Color.green;
        if (GUILayout.Button("Replace All", GUILayout.Height(EditorGUIUtility.singleLineHeight * 2f)))
        {
            ReplaceFonts(_src, _dest, _includePrefabs);
        }
        GUI.color = Color.white;
    }

    private static void ReplaceFonts(Font src, Font dest, bool includePrefabs)
    {
        var sceneMatches = 0;
        for (var i = 0; i < SceneManager.sceneCount; i++)
        {
            var scene = SceneManager.GetSceneAt(i);
            var gos = new List<GameObject>(scene.GetRootGameObjects());
            foreach (var go in gos)
            {
                sceneMatches += ReplaceFonts(src, dest, go.GetComponentsInChildren<Text>(true));
            }
        }

        if (includePrefabs)
        {
            var prefabMatches = 0;
            var prefabs =
                AssetDatabase.FindAssets("t:Prefab")
                    .Select(guid => AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(guid)));
            foreach (var prefab in prefabs)
            {
                prefabMatches += ReplaceFonts(src, dest, prefab.GetComponentsInChildren<Text>(true));
            }

            Debug.LogFormat("Replaced {0} font(s), {1} in scenes, {2} in prefabs", sceneMatches + prefabMatches, sceneMatches, prefabMatches);
        }
        else
        {
            Debug.LogFormat("Replaced {0} font(s) in scenes", sceneMatches);
        }
    }

    private static int ReplaceFonts(Font src, Font dest, IEnumerable<Text> texts)
    {
        var matches = 0;
        var textsFiltered = src != null ? texts.Where(text => text.font == src) : texts;
        foreach (var text in textsFiltered)
        {
            text.font = dest;
            matches++;
        }
        return matches;
    }

    private static string GetAssetPath(Object assetObject, string defaultExtension)
    {
        var path = AssetDatabase.GetAssetPath(assetObject);
        if (path.StartsWith("Library/", System.StringComparison.InvariantCultureIgnoreCase))
            path = assetObject.name + "." + defaultExtension;
        return path;
    }
}

Not sure if there’s something in the editor tha can do it but you can swap them out when the game loads with this.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class TextChanger : MonoBehaviour {

	private Text[] GetText;
	public Font myFont;

	// Use this for initialization
	void Start () {
		GetText = Text.FindObjectsOfType<Text> ();

		foreach (Text go in GetText)
			go.font = myFont;
	}
}

It’s not very good practice though so if someone knows an editor trick to change them go with that.

EDIT - forgot to say, you need that script on any gameObject in each and every scene. It runs when the scene starts so if you have a prefab that instantiates later it may not catch that.

Thanks for the Script, I updated it for TextMeshPro :wink:

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;

public class TMProFontReplacer : EditorWindow
{
	private const string EditorPrefsKey = "Utilities.TMProFontReplacer";
	private const string MenuItemName = "Utilities/Replace TMProFonts...";

	private TMP_FontAsset _src;
	private TMP_FontAsset _dest;
	private bool _includePrefabs;

	[MenuItem(MenuItemName)]
	public static void DisplayWindow()
	{
		var window = GetWindow<TMProFontReplacer>(true, "Replace TMProFonts");
		var position = window.position;
		position.size = new Vector2(position.size.x, 151);
		position.center = new Rect(0f, 0f, Screen.currentResolution.width, Screen.currentResolution.height).center;
		window.position = position;
		window.Show();
	}

	public void OnEnable()
	{
		var path = EditorPrefs.GetString(EditorPrefsKey + ".src");
		if (path != string.Empty)
			_src = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(path) ?? Resources.GetBuiltinResource<TMP_FontAsset>(path);

		path = EditorPrefs.GetString(EditorPrefsKey + ".dest");
		if (path != string.Empty)
			_dest = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(path) ?? Resources.GetBuiltinResource<TMP_FontAsset>(path);

		_includePrefabs = EditorPrefs.GetBool(EditorPrefsKey + ".includePrefabs", false);
	}

	public void OnGUI()
	{
		EditorGUI.BeginChangeCheck();
		EditorGUILayout.PrefixLabel("Find:");
		_src = (TMP_FontAsset)EditorGUILayout.ObjectField(_src, typeof(TMP_FontAsset), false);

		EditorGUILayout.Space();
		EditorGUILayout.PrefixLabel("Replace with:");
		_dest = (TMP_FontAsset)EditorGUILayout.ObjectField(_dest, typeof(TMP_FontAsset), false);

		EditorGUILayout.Space();
		_includePrefabs = EditorGUILayout.ToggleLeft("Include Prefabs", _includePrefabs);
		if (EditorGUI.EndChangeCheck())
		{
			EditorPrefs.SetString(EditorPrefsKey + ".src", GetAssetPath(_src, "ttf"));
			EditorPrefs.SetString(EditorPrefsKey + ".dest", GetAssetPath(_dest, "ttf"));
			EditorPrefs.SetBool(EditorPrefsKey + ".includePrefabs", _includePrefabs);
		}

		GUI.color = Color.green;
		if (GUILayout.Button("Replace All", GUILayout.Height(EditorGUIUtility.singleLineHeight * 2f)))
		{
			ReplaceFonts(_src, _dest, _includePrefabs);
		}
		GUI.color = Color.white;
	}

	private static void ReplaceFonts(TMP_FontAsset src, TMP_FontAsset dest, bool includePrefabs)
	{
		var prefabMatches = 0;
		if (includePrefabs)
		{
			var prefabs =
				AssetDatabase.FindAssets("t:Prefab")
					.Select(guid => AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(guid)));
			foreach (var prefab in prefabs)
			{
				prefabMatches += ReplaceFonts(src, dest, prefab.GetComponentsInChildren<TextMeshProUGUI>(true));
				UnityEditor.EditorUtility.SetDirty(prefab);
			}
		}

		var sceneMatches = 0;
		for (var i = 0; i < SceneManager.sceneCount; i++)
		{
			var scene = SceneManager.GetSceneAt(i);
			var gos = new List<GameObject>(scene.GetRootGameObjects());
			foreach (var go in gos)
			{
				sceneMatches += ReplaceFonts(src, dest, go.GetComponentsInChildren<TextMeshProUGUI>(true));
			}
		}
		UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();

		if (includePrefabs)
		{
			Debug.LogFormat("Replaced {0} font(s), {1} in scenes, {2} in prefabs", sceneMatches + prefabMatches, sceneMatches, prefabMatches);
		}
		else
		{
			Debug.LogFormat("Replaced {0} font(s) in scenes", sceneMatches);
		}
	}

	private static int ReplaceFonts(TMP_FontAsset src, TMP_FontAsset dest, IEnumerable<TextMeshProUGUI> texts)
	{
		var matches = 0;
		var textsFiltered = src != null ? texts.Where(text => text.font == src) : texts;
		foreach (var text in textsFiltered)
		{
			text.font = dest;
			matches++;
		}
		return matches;
	}

	private static string GetAssetPath(Object assetObject, string defaultExtension)
	{
		var path = AssetDatabase.GetAssetPath(assetObject);
		if (path.StartsWith("Library/", System.StringComparison.InvariantCultureIgnoreCase))
			path = assetObject.name + "." + defaultExtension;
		return path;
	}
}

Thanks for the script.

Note to add:

UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene);

So you can then Save the changes to the scene.

for who could not figure out how to use it:
After creating your above script(s). click the search button on unity editor (MAGNIFICATION symbol). then search for Replace Font. click the result. it will open a window where it allows you to replace all fonts.

thanks for the code guys.