Text Auto Sizing requires multiple passes to determine the optimum point size for the given text container size. This can have significant performance overhead and has such I do not recommend using auto size on all text objects.
In addition to performance overhead, using auto size on different text objects is likely to result in different point size which from a design point of view is not ideal. For instance, if you have 5 buttons in a UI, the text point size should be the same for all of them. It is fine to use different point size but similar text objects should use the same point size.
My recommendation is to identify groups of text objects that should have the same point size. Then for each group, use one of the text objects, typically the one with the most characters to figure out the optimum point size. Then disabling auto size on this test object and then manually set the point size on it and the other text objects in that group. This ensures auto size is only used once per group of text objects.
You should maintain a list of these groups and list of text objects within these groups. Whenever a new scene is loaded, you would iterate through the relevant groups to as per above find the optimum point size and then manually setting it on the other relevant text objects.
In terms of changing point size, changing the .fontSize property will change the point size. On the object you are testing since you want this result within the same frame, you will have to use the ForceMeshUpdate() on the text object. As such you would …
Here is a very simple implementation example
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class TextAutoSizeController : MonoBehaviour
{
public TMP_Text[] TextObjects;
private void Awake()
{
if (TextObjects == null || TextObjects.Length == 0)
return;
// Iterate over each of the text objects in the array to find a good test candidate
// There are different ways to figure out the best candidate
// Preferred width works fine for single line text objects
int candidateIndex = 0;
float maxPreferredWidth = 0;
for (int i = 0; i < TextObjects.Length; i++)
{
float preferredWidth = TextObjects[i].preferredWidth;
if (preferredWidth > maxPreferredWidth)
{
maxPreferredWidth = preferredWidth;
candidateIndex = i;
}
}
// Force an update of the candidate text object so we can retrieve its optimum point size.
TextObjects[candidateIndex].enableAutoSizing = true;
TextObjects[candidateIndex].ForceMeshUpdate();
float optimumPointSize = TextObjects[candidateIndex].fontSize;
// Disable auto size on our test candidate
TextObjects[candidateIndex].enableAutoSizing = false;
// Iterate over all other text objects to set the point size
for (int i = 0; i < TextObjects.Length; i++)
TextObjects[i].fontSize = optimumPointSize;
}
}
Add the following scrip to an empty game object. Populate the public array with text objects that all have auto size disabled. These would be text objects that you expect to end up all at the same point size.
Screen shot of the scene setup before entering playmode
Result when using just auto size on these objects
As you can see they end up with different point size which is weird from a design point of view.
Now with auto size disabled and using the example script we get the following result.
In this case they are all using the same final point size and we only used auto size on one text object so better performance.
Since auto size is typically used to handle resolution variance between devices which is something that needs to be addressed when loading a scene the first time, this also means we only have to do this once unless the text will be changing of course.