c# - Unity如何正确获取字符宽度

标签 c# unity3d unity-editor

我正在尝试创建一个脚本,当一行文本接近该行的宽度时,它会尝试正确地换行文本(即,如果字符不是“-”或“”,则添加一个连字符在一个单词的字母之间(就像单词编辑软件的工作方式一样)但是当我尝试运行它时,我的一堆字符消失了。

这是我正在测试的文本,“畸变体具有奇异的解剖结构、奇怪的能力、外星人的思维方式,或三者的任意组合。”

但这些是我的测试脚本的结果

"找到信息 (' ','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 检查您使用的字体是否定义了字符 - 如果返回 false,则该字符不存在于字体中并且无法加载使用。示例是检查仅包含拉丁字符的字体中的非拉丁符号。 Font.HasCharacter 返回 true 意味着您可以将该字符加载到字体纹理中。

Font.GetCharacterInfo 从当前加载的字体纹理中获取有关符号的信息 - 因此加载的字体可能有可用的字符,但未加载;如果您手动呈现文本,这将导致 Font.GetCharacterInfo 返回 false 并使字符不呈现。要解决这个问题,您需要使用 RequestCharactersInTexture 请求 Unity 加载您需要的角色。 - 文档还包含有关如何处理手动文本渲染(包括字体纹理更新)的示例。在加载字符之前,您将无法获取其字体信息,因为它不存在于当前使用的字体纹理中。调用 RequestCharactersInTexture 时,传递文本中出现的所有字符,无论它们是否已加载 - 这样可以确保 Font 在加载新字符时不会卸载之前加载的字符。

确定换行符

在制定解决方案以确定在哪里放置换行符时,您可能需要使用 kerning考虑到 - 根据周围的字符,字体可能希望在字符之间使用不同的距离,有时甚至使用不同的字形。如果您手动呈现文本,请确保在计算换行符之间对字距调整有一致的处理 - 没有字距调整是一个好的策略,只要您使用的字体不严重依赖于字距调整。如果你想支持字距调整,你应该处理子字符串而不是单个字符,并尝试找到为整行引入换行符的最佳点 - 一行的宽度可能不同于该行中出现的所有字符宽度的总和。

关于c# - Unity如何正确获取字符宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67597642/

相关文章:

unity3d - 使用 Unity 2020 及更高版本,如何为 Windows 构建单个文件?

c# - 如何统一存储 256 位整数?

ios - 是否可以将Unity与UIKit混合使用?

c# - 在具有物理和刚体的移动物体上与玩家保持一致在 Unity 中不起作用

C# Exchange ActiveSync 客户端

c# - 在 Swagger for ASP .NET Core 3.1 中为标题添加过滤器

c# - 如何在 Windows 8 中访问日历

c# - Unity 数组 C# 的自定义下拉选择

c# - Unity 广告没有自动初始化?

c# - 当数组参数的值为空时,无法确定其类型