修改TextMeshPro,实现伪动态字体。

在使用TextMeshPro,一般来说会将UI上需要显示的文字制作成静态字体,只有在聊天框或者名字输入框等需要用户输入的地方才会使用动态字体,但是如果完全的使用动态字体怎么办呢?其实TMP已经内置了动态字体模式,只需要将字体的的 Generation Settings -> Atlas Population Mode 设置为 Dynamic 即可, 但是这种方式只能支持一张Atlas,当要这张Atlas被填满时,新出现的文字将会显示异常。所以为了实现这个需求,扁扁做了一点微小的工作。大致的思路是利用TMP的回滚字体,当主字体的Atlas被填满时,就自动生成一个回滚字体。

话不多说,上代码吧。

TMP_FontAsset.cs

void Awake()
{
    //Debug.Log("TMP Font Asset [" + this.name + "] with Version #" + m_Version + " has been enabled!");

    // Check version number of font asset to see if it needs to be upgraded.
    if (this.material != null && string.IsNullOrEmpty(m_Version))
        UpgradeFontAsset();

    if (m_AtlasPopulationMode == AtlasPopulationMode.Dynamic)
    {
        ClearFallbackFont();
    }

}

public delegate void FontLoader(out Font font);
public static FontLoader fontLoader;

public bool IncreaseFallbackFontAsset()
{
	Font font = null;
	if (Application.isPlaying) {
		fontLoader?.Invoke(out font);
	} else {
		font = Resources.Load<Font>("simhe");
	}

	if (font == null)
	{
		return false;
	}
#if UNITY_EDITOR
	else
	{
		Debug.Log("加载字体: " + font.name);
	}
#endif
	TMP_FontAsset fontAsset = CreateFontAsset(font);
	m_FallbackFontAssetTable.Add(fontAsset);
	fontAsset.hideFlags = HideFlags.NotEditable;
	return true;
}

public void ClearFallbackFont()
{
	if (m_FallbackFontAssetTable != null && m_FallbackFontAssetTable.Count > 0)
		m_FallbackFontAssetTable.Clear();
}

 

TMP_Text.cs

protected virtual void IncreaseFallbackFont()
{
    if (!m_fontAsset.IncreaseFallbackFontAsset())
    {
        Debug.LogError("[ERROR]增加回滚字体失败");
    }
#if UNITY_EDITOR
    else
    {
        Debug.Log("增加一个后备字体 总数: " + m_fontAsset.fallbackFontAssetTable.Count);
    }
#endif
}

 

TMPro_UGUI_Private.cs

然后在 TMPro_UGUI_Private.cs 中的 SetArraySizes 方法中的添加如下代码

#region LOOKUP GLYPH
character = TMP_FontAssetUtilities.GetCharacterFromFontAsset((uint)unicode, m_currentFontAsset, false, m_FontStyleInternal, m_FontWeightInternal, out isUsingAlternativeTypeface, out tempFontAsset);

// Search for the glyph in the list of fallback assigned to the primary font asset.
if (character == null)
{
    if (m_currentFontAsset.fallbackFontAssetTable != null && m_currentFontAsset.fallbackFontAssetTable.Count > 0)
        character = TMP_FontAssetUtilities.GetCharacterFromFontAssets((uint)unicode, m_currentFontAsset.fallbackFontAssetTable, true, m_FontStyleInternal, m_FontWeightInternal, out isUsingAlternativeTypeface, out tempFontAsset);
}

// 下面的代码是要添加的代码
if (m_currentFontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic && character == null)
{
    IncreaseFallbackFont();
    if (m_currentFontAsset.fallbackFontAssetTable != null && m_currentFontAsset.fallbackFontAssetTable.Count > 0)
        character = TMP_FontAssetUtilities.GetCharacterFromFontAssets((uint)unicode, m_currentFontAsset.fallbackFontAssetTable, true, m_FontStyleInternal, m_FontWeightInternal, out isUsingAlternativeTypeface, out tempFontAsset);
}

 

这样就实现了一个伪动态的TMP的字体啦。

最后需要再监听一下Editor中的play和stop事件以及打包前的事件,在play之前和stop之后以及打包前清除掉主字体的回滚字体就行啦。

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像