• Home
  • Store
    Show / Hide Table of Contents

    Notes on TextMesh Pro

    SubMesh Objects

    True Shadow supports TMP. However, due to its use of submesh objects, additional code may be necessary.

    When using multiple fonts on a TMP, including fallback fonts, glyphs using fonts other than the primary font are rendered with SubMesh objects. Since these are separated UI elements, they need their own True Shadow component.

    Tip

    You can make these objects visible under Project Settings > TextMesh Pro > Settings > Hide Sub Text Objects. If this setting doesn't exist, they should already be visible.

    Static text

    For texts that don't changes at runtime, you can use the Copy to Sub-Meshes button in the inspector to apply the shadow from the main TMP on any submeshes to preview changes in the inspector. At the start, this is also done automatically.

    Dynamic text

    If the text are dynamically changed at runtime, some code are neccesarry. These submesh objects don't send the usual dirty signals like other UIs, so True Shadow can't detect when they're changed without expensive polling. When you change these submeshes, you need to call TrueShadow.CopyToTMPSubMeshes() to update the shadow on the submeshes.

    Since the submeshes are not generated until Canvas.willRenderCanvases, you likely have to delay calling this function:

    using UnityEngine;
    using LeTai.TrueShadow;
    
    public class ChangeLocalizedText : MonoBehaviour
    {
        private TMPro.TextMeshProUGUI tmp;
        private TrueShadow            trueShadow;
    
        private void Awake()
        {
            tmp = GetComponent<TMPro.TextMeshProUGUI>();
            trueShadow = GetComponent<TrueShadow>();
        }
    
        void Start()
        {
            Canvas.willRenderCanvases += OnWillRenderCanvases;
        }
    
        bool needUpdateTMPSubmeshesShadow = false;
    
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                tmp.text = Time.frameCount;
                needUpdateTMPSubmeshesShadow = true;
            }
        }
    
        void OnWillRenderCanvases()
        {
            if (needUpdateTMPSubmeshesShadow)
            {
                needUpdateTMPSubmeshesShadow = false;
                trueShadow.CopyToTMPSubMeshes();
            }
        }
    }
    

    Still doesn't work?

    When no longer in use, the submesh objects are hidden using CanvasRenderer.SetMesh(null). Before Unity 2022.2, there is no way to detect this. Thus, in those versions, you need to destroy the objects to get their shadow to disappear. They will be regenerated by TMP when needed.

    ...
            if (Input.GetMouseButtonDown(0))
            {
                tmp.text = Time.frameCount;
                
                // Needed before Unity 2022.2
                var submeshes = GetComponentsInChildren<TMPro.TMP_SubMeshUI>();
                for (var i = 0; i < submeshes.Length; i++)
                {
                    Destroy(submeshes[i].gameObject);
                }
    
                needUpdateTMPSubmeshesShadow = true;
            }
    ...
    
    In This Article
    Like True Shadow? Your review is greatly appreciated! ⭐⭐⭐⭐⭐ Back to top