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
相关产品推荐
相关产品推荐

