長いTextの終わりに "..." をつけ、かつ改行させない方法

Textの幅が枠内に収まりきらないとき、私たちのチームでは、以下の記事の`(4) 余談`の部分を参考に、溢れない箇所でカットして、 `...` を末尾に付与しています。  

[[Unity] Textコンポーネントでテキストを切り捨てずに全文表示させる方法 ](https://qiita.com/lycoris102/items/219455968fbfd29fddc9)

![スクリーンショット 2019-12-06 16.03.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34656/722fac2b-a93d-311a-95d5-d8a3b6c80e3f.png)


以下に一部引用させていただきます。  

```cs

public static void SetTextWithEllipsis(this Text textComponent, string value)
{
    // create generator with value and current Rect
    var generator = new TextGenerator();
    var rectTransform = textComponent.GetComponent<RectTransform>();
    var settings = textComponent.GetGenerationSettings(rectTransform.rect.size);
    generator.Populate(value, settings);

    // trncate visible value and add ellipsis
    var characterCountVisible = generator.characterCountVisible;
    var updatedText = value;
    if (value.Length > characterCountVisible)
    {
        updatedText = value.Substring(0, characterCountVisible - 3);
        updatedText += "...";
    }

    // update text
    textComponent.text = updatedText;
}
```

しかし、あるとき問題が発覚しました。長い文字列に半角スペースが含まれている場合、
そのスペースで改行されてしまい、↑のコードはその1行目の終わりで可視文字列の終わりと判定されて、右にまだスペースがあるのに早々に`...`が打たれて残りが全てカットされてしまうのです。（↓の中身は、「あああああ\nあああああ\nあああああ」のようになっていますが、1行目の最後の文字がリミットと判断されるようです）  

![スクリーンショット 2019-12-06 18.02.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34656/536dc179-42fc-0954-bfcb-aec760a905b6.png)

かといって、TextのHorizontal OverflowをOverflowにすると、今度は全て表示可能とみなされ、`...`を付与されず全部そのまま出てしまいます…。 

![スクリーンショット 2019-12-06 18.03.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34656/544eb7ed-8641-7b20-5ca5-1db91a858656.png)

（ただし、この問題は英語のみでは起きないようです。）

![スクリーンショット 2019-12-06 17.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34656/4aab9b19-e43e-7348-191f-e68e5081a93b.png)

そこで、私たちがとった対策は、半角スペースをnbsp(non-breaking space)に置き換えることです。  

このnbsp、htmlなどでは`&nbsp;`としてご存知の方もいるかと思いますが、文字コードとしても存在します(`\u00a0`)。  
改行を誘発する半角スペースをnbspに置き換えてしまうことで、改行を抑制するわけです。  
上記のコードを書き換えるなら、以下のようになります。  

```cs

public static void SetTextWithEllipsis(this Text textComponent, string value, bool spaceToNbsp)
{
    // create generator with value and current Rect
    var generator = new TextGenerator();
    var rectTransform = textComponent.GetComponent<RectTransform>();
    var settings = textComponent.GetGenerationSettings(rectTransform.rect.size);
    if (spaceToNbsp)
    {
        value = value.Replace(" ", "\u00a0");
    }
    generator.Populate(value, settings);

    // trncate visible value and add ellipsis
    var characterCountVisible = generator.characterCountVisible;
    var updatedText = value;
    if (value.Length > characterCountVisible)
    {
        updatedText = value.Substring(0, characterCountVisible - 3);
        updatedText += "...";
    }

    // update text
    textComponent.text = updatedText;
}
```

やってることとしては単純で、`Populate()` の前に文字列を `Replace()`しているだけです。  
これで、半角スペースが含まれていても単語で区切らずに `...` を付与することができました。  

![スクリーンショット 2019-12-06 18.03.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34656/7befc028-3f87-bca1-ef56-b75c7f5f65a1.png)

英語では問題が起きないところを見るとUnityの処理の不具合のような気もしますが、ともかくこれで想定どおりの挙動になりました。