You need to enable JavaScript to run this app. Unity如何正确获取字符宽度 解决自定义文本换行字符丢失问题
优惠活动
大模型
产品
解决方案
定价
更多

Unity如何正确获取字符宽度 解决自定义文本换行字符丢失问题

问题根因

你的测试结果中Didnt Find列表为空,说明Arial字体完全支持测试文本里的所有字符,拿不到CharacterInfo是Unity字体的默认机制导致的:默认动态字体只会把已经渲染过的字符信息存入缓存,未渲染过的字符直接调用GetCharacterInfo会返回失败,就是你看到的Found without info列表里的字符。

修复步骤
  • 第一步调整字体导入配置:选中项目里的Arial字体资源,在Inspector面板中将Character Set选项设置为「Unicode」,或者手动填入你业务中会用到的所有字符生成自定义字符集,避免运行时动态加载字符信息失败。
  • 第二步在获取字符信息前预加载字符:调用Font.RequestCharactersInTexture()接口主动把你需要的文本字符加载到字体纹理中,加载完成后再调用GetCharacterInfo就能正常拿到信息。
  • 第三步调整检测逻辑的执行时机:RequestCharactersInTexture是异步操作,调用后立刻检测还是会拿不到信息,建议延迟一帧执行,或者注册字体加载回调后再执行检测。
修改后的参考代码
public class Test : MonoBehaviour
{
    [SerializeField] 
    private Type m_Type; 
    // 不是System.Type,是自定义类

    [SerializeField] 
    private Font m_Font; 
    // 测试用设置为Arial

    private List<string> m_FoundWithInfo;
    private List<string> m_FoundWithoutInfo;
    private List<string> m_DidntFind;
    private const int FONT_SIZE = 14;
    private const FontStyle FONT_STYLE = FontStyle.Normal;

    private IEnumerator Start()
    {
        m_FoundWithInfo = new List<string>();
        m_FoundWithoutInfo = new List<string>();
        m_DidntFind = new List<string>();
        string testText = m_Type.GetDescription();
        // 预加载所有需要的字符
        m_Font.RequestCharactersInTexture(testText, FONT_SIZE, FONT_STYLE);
        // 延迟一帧等字符加载完成
        yield return null;
        foreach (char c in testText)
        {
            if (m_Font.HasCharacter(c))
            {
                if (m_Font.GetCharacterInfo(c, out CharacterInfo info, FONT_SIZE, FONT_STYLE))
                {
                    if (!m_FoundWithInfo.Contains($"'{c}'"))
                    {
                        m_FoundWithInfo.Add($"'{c}'");
                    }
                }
                else
                {
                    if (!m_FoundWithoutInfo.Contains($"'{c}'"))
                    {
                        m_FoundWithoutInfo.Add($"'{c}'");
                    }
                }
            }
            else
            {
                if (!m_DidntFind.Contains($"'{c}'"))
                {
                    m_DidntFind.Add($"'{c}'");
                }
            }
        }
        Debug.Log($"Found with info ({string.Join(",", m_FoundWithInfo)})");
        Debug.Log($"Found without info ({string.Join(",", m_FoundWithoutInfo)})");
        Debug.Log($"Didnt Find ({string.Join(",", m_DidntFind)})");
    }
}
额外注意事项
  • 你的换行逻辑要等所有字符的CharacterInfo都成功获取后再执行,避免行宽计算错误导致换行位置不对。
  • 如果需要支持任意字符输入,建议将字体的渲染模式设置为Hinted Raster,避免动态生成字符纹理时出现模糊或者信息缺失的问题。

内容的提问来源于stack exchange,提问作者user3915050

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 05:54:03