Unity如何正确获取字符宽度
Unity How to get get a characters width properly
我正在尝试创建一个脚本,当一行文本接近该行的宽度时,它会尝试正确地换行文本(即,如果字符不是“-”或“”,则添加单词字母之间的连字符(就像单词编辑软件的工作方式一样)但是当我尝试 运行 它时,我的一堆字符消失了。
这是我正在测试的文本,“畸变体具有奇异的解剖结构、奇怪的能力、外星人的思维方式,或三者的任意组合。”
但这些是我的测试脚本的结果
"找到信息(' ','e','r','a','t','i','o','h','s','l','d')"
"发现没有信息 ('A','n','b','z','m','y',',','g' ,'c','f','.')"
“没有找到 ()”
并且仅使用具有可用信息的字符编译文本的输出是“erratio has a iarre aato strae ailities a ali idset or a oiatio o the three”
这是我的测试脚本
public class Test : MonoBehaviour
{
[SerializeField]
private Type m_Type;
// Not System.Type, is a custom class
[SerializeField]
private Font m_Font;
// Set to Arial for testing.
private List<string> m_FoundWithInfo;
private List<string> m_FoundWithoutInfo;
private List<string> m_DidntFind;
private void Awake()
{
m_FoundWithInfo = new List<string>();
m_FoundWithoutInfo = new List<string>();
m_DidntFind = new List<string>();
foreach (char c in m_Type.GetDescription())
{
if (m_Font.HasCharacter(c))
{
if (m_Font.GetCharacterInfo(c,
out CharacterInfo info, 14, FontStyle.Normal))
{
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。
正在获取角色信息
Unity 字体管理对纹理进行操作以渲染字符,在渲染文本时使用它们之前,需要告知加载哪些字符以便将它们添加到字体纹理中。除非您请求在您的示例之外加载字符,否则字体中存在但没有可用信息的字符是因为当您查询字体的信息时没有将它们加载到字体纹理中。
Font.HasCharacter
检查您使用的字体是否定义了字符 - 如果它 return 为假,则该字符不存在于字体中并且无法加载使用。示例是检查仅包含拉丁字符的字体中的非拉丁符号。 Font.HasCharacter
return为真意味着您可以将该字符加载到字体纹理中。
Font.GetCharacterInfo
从当前加载的字体纹理中获取有关符号的信息 - 因此加载的字体可能有可用的字符,但未加载;如果您手动渲染文本,这将导致 Font.GetCharacterInfo
到 return false 并使角色无法渲染。要解决此问题,您需要使用 RequestCharactersInTexture 请求 Unity 加载您需要的字符 - 文档还包含有关如何处理手动文本渲染(包括字体纹理更新)的示例。在加载字符之前,您将无法获取其字体信息,因为它不存在于当前使用的字体纹理中。调用 RequestCharactersInTexture
时,传递文本中出现的所有字符,无论它们是否已加载 - 这样可以确保 Font 在加载新字符时不会卸载之前加载的字符。
确定换行符
在确定换行位置的解决方案时,您可能需要考虑 kerning - 根据周围的字符,字体可能需要使用不同的字符间距,有时甚至需要使用不同的字符间距字形。如果您手动呈现文本,请确保在计算换行符之间对字距调整有一致的处理 - 没有字距调整是一个好的策略,只要您使用的字体不严重依赖于字距调整。如果你想支持字距调整,你应该处理子字符串而不是单个字符,并尝试找到为整行引入换行符的最佳点 - 一行的宽度可能不同于该行中出现的所有字符宽度的总和。
我正在尝试创建一个脚本,当一行文本接近该行的宽度时,它会尝试正确地换行文本(即,如果字符不是“-”或“”,则添加单词字母之间的连字符(就像单词编辑软件的工作方式一样)但是当我尝试 运行 它时,我的一堆字符消失了。
这是我正在测试的文本,“畸变体具有奇异的解剖结构、奇怪的能力、外星人的思维方式,或三者的任意组合。”
但这些是我的测试脚本的结果
"找到信息(' ','e','r','a','t','i','o','h','s','l','d')" "发现没有信息 ('A','n','b','z','m','y',',','g' ,'c','f','.')" “没有找到 ()”
并且仅使用具有可用信息的字符编译文本的输出是“erratio has a iarre aato strae ailities a ali idset or a oiatio o the three”
这是我的测试脚本
public class Test : MonoBehaviour
{
[SerializeField]
private Type m_Type;
// Not System.Type, is a custom class
[SerializeField]
private Font m_Font;
// Set to Arial for testing.
private List<string> m_FoundWithInfo;
private List<string> m_FoundWithoutInfo;
private List<string> m_DidntFind;
private void Awake()
{
m_FoundWithInfo = new List<string>();
m_FoundWithoutInfo = new List<string>();
m_DidntFind = new List<string>();
foreach (char c in m_Type.GetDescription())
{
if (m_Font.HasCharacter(c))
{
if (m_Font.GetCharacterInfo(c,
out CharacterInfo info, 14, FontStyle.Normal))
{
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。
正在获取角色信息
Unity 字体管理对纹理进行操作以渲染字符,在渲染文本时使用它们之前,需要告知加载哪些字符以便将它们添加到字体纹理中。除非您请求在您的示例之外加载字符,否则字体中存在但没有可用信息的字符是因为当您查询字体的信息时没有将它们加载到字体纹理中。
Font.HasCharacter
检查您使用的字体是否定义了字符 - 如果它 return 为假,则该字符不存在于字体中并且无法加载使用。示例是检查仅包含拉丁字符的字体中的非拉丁符号。 Font.HasCharacter
return为真意味着您可以将该字符加载到字体纹理中。
Font.GetCharacterInfo
从当前加载的字体纹理中获取有关符号的信息 - 因此加载的字体可能有可用的字符,但未加载;如果您手动渲染文本,这将导致 Font.GetCharacterInfo
到 return false 并使角色无法渲染。要解决此问题,您需要使用 RequestCharactersInTexture 请求 Unity 加载您需要的字符 - 文档还包含有关如何处理手动文本渲染(包括字体纹理更新)的示例。在加载字符之前,您将无法获取其字体信息,因为它不存在于当前使用的字体纹理中。调用 RequestCharactersInTexture
时,传递文本中出现的所有字符,无论它们是否已加载 - 这样可以确保 Font 在加载新字符时不会卸载之前加载的字符。
确定换行符
在确定换行位置的解决方案时,您可能需要考虑 kerning - 根据周围的字符,字体可能需要使用不同的字符间距,有时甚至需要使用不同的字符间距字形。如果您手动呈现文本,请确保在计算换行符之间对字距调整有一致的处理 - 没有字距调整是一个好的策略,只要您使用的字体不严重依赖于字距调整。如果你想支持字距调整,你应该处理子字符串而不是单个字符,并尝试找到为整行引入换行符的最佳点 - 一行的宽度可能不同于该行中出现的所有字符宽度的总和。