简体   繁体   English

Unity如何正确获取字符宽度

[英]Unity How to get get a characters width properly

I am attempting to create a script that when a line of text would be approaching the width of the line it would attempt to wrap the text properly (ie. if the character is not '-' or ' ' then add a hyphen between letters of a word (like how word editing software does it) but when I attempt to run it a bunch of my characters disappear.我正在尝试创建一个脚本,当一行文本接近行宽时,它会尝试正确换行(即,如果字符不是“-”或“”,则在字母之间添加连字符一个单词(就像文字编辑软件是如何做到的)但是当我尝试运行它时,我的一堆字符消失了。

This is the text that I am testing with, "An Aberration has a bizarre anatomy, strange abilities, an alien mindset, or any combination of the three."这是我正在测试的文本,“畸变具有奇异的解剖结构、奇怪的能力、外星人的思维方式,或三者的任意组合。”

but these are the results of my test script但这些是我的测试脚本的结果

"Found with info (' ','e','r','a','t','i','o','h','s','l','d')" "Found without info ('A','n','b','z','m','y',',','g','c','f','.')" "Didnt Find ()" "找到信息 ('','e','r','a','t','i','o','h','s','l','d')" "发现没有信息 ('A','n','b','z','m','y',',','g','c','f','.')" "没找到()”

and the output from compiling the text using only the characters that have available info is " erratio has a iarre aato strae ailities a alie idset or a oiatio o the three"和 output 仅使用具有可用信息的字符编译文本是“错误有一个 iarre aato strae ailities a alie idset 或一个 oiatio o 三个”

and here is my testing script这是我的测试脚本

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)})");
    }
}

How can I make this work so that the returned text is otherwise identical to the original?我怎样才能使这项工作,以使返回的文本在其他方面与原始文本相同?

To clarify the Test script only checks to see what necessary characters don't have any CharacterInfo associated with them.为了澄清测试脚本,只检查哪些必要的字符没有与之关联的任何 CharacterInfo。

Getting character info获取角色信息

Unity font management operates on textures to render characters, and needs to be informed what characters to load in order to add them to a font texture, before you can use them while rendering text. Unity 字体管理对纹理进行操作以渲染字符,并且需要通知要加载哪些字符才能将它们添加到字体纹理,然后才能在渲染文本时使用它们。 Unless you request loading characters outside your example, having characters that exist in a font but don't have info available are due to not having them loaded into a font texture when you query font for their info.除非您请求在示例之外加载字符,否则字体中存在但没有可用信息的字符是由于在查询字体以获取其信息时没有将它们加载到字体纹理中。

Font.HasCharacter checks if a font you use has character defined - if it returns false, that character doesn't exist in a font and can't be loaded to be used. Font.HasCharacter检查您使用的字体是否定义了字符 - 如果返回 false,则该字符在字体中不存在并且无法加载以供使用。 Example would be checking a non-latin symbol in font that covers only latin characters.例如,检查仅涵盖拉丁字符的字体中的非拉丁符号。 Font.HasCharacter returning true means you can load that character to a font texture. Font.HasCharacter返回 true 意味着您可以将该字符加载到字体纹理中。

Font.GetCharacterInfo get information about a symbol from currently loaded font texture - so there is a possibility that loaded font may have a character available, but not loaded; Font.GetCharacterInfo从当前加载的字体纹理中获取有关符号的信息 - 因此加载的字体可能有可用的字符,但未加载; this will cause Font.GetCharacterInfo to return false and make character not render if your render text manually.如果您手动渲染文本,这将导致Font.GetCharacterInfo返回 false 并使字符不渲染。 To work around that, you need to request Unity to load characters you will need by using RequestCharactersInTexture - documentation also contains an example on how to handle manual text rendering including font texture updates.要解决这个问题,您需要使用RequestCharactersInTexture请求 Unity 加载您需要的字符 - 文档还包含有关如何处理手动文本渲染(包括字体纹理更新)的示例。 Until you have a character loaded, you won't be able to get its font info, since it doesn't exist in currently used Font texture.在加载字符之前,您将无法获取其字体信息,因为它不存在于当前使用的字体纹理中。 When calling RequestCharactersInTexture , pass all characters that occur in your text regardless if they're loaded or not - that way you make sure Font won't unload a character that was previously loaded when loading new ones.调用RequestCharactersInTexture时,传递文本中出现的所有字符,无论它们是否已加载 - 这样您就可以确保 Font 在加载新字符时不会卸载先前加载的字符。

Determining line breaks确定换行符

When working on a solution to determine where to put line breaks, you may need to take kerning into account - depending on surrounding characters, font may want to use different distance between characters or sometimes even use different glyphs.在制定解决方案以确定在何处放置换行符时,您可能需要考虑字距调整- 根据周围的字符,字体可能希望在字符之间使用不同的距离,有时甚至使用不同的字形。 If you render text manually, make sure to have consistent handling of kerning between calculating linebreaks - no kerning is a good strategy, as long as font you're using doesn't depend heavily on kerning.如果您手动渲染文本,请确保在计算换行符之间对字距进行一致的处理 - 没有字距调整是一个好策略,只要您使用的字体不严重依赖字距调整。 If you want to support kerning, you should work on substrings instead of single characters and try to find best points of introducing line break for a whole line - width of a line may be different from sum of all character widths that occur in said line.如果您想支持字距调整,您应该处理子字符串而不是单个字符,并尝试找到为整行引入换行符的最佳点 - 行的宽度可能与所述行中出现的所有字符宽度的总和不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM