2
1

TextMeshProで1文字ずつ表示していると、前の行の文字が移動する事がある

Posted at

メッセージを1文字ずつ表示するウィンドウを作っていたら、前の行の文字が突然次の行に移動した

45064a4d874d2329555e5c04fe1f5f73.gif

原因

TextMeshProはデフォルトで禁則処理が入っており
運悪く、自動改行した次の行の頭の文字が行頭禁則に引っかかって
前の行の最後の文字が、新しい行の先頭に追い出されていた。

どうしよう

事前に改行する位置を調べて、予め改行コードを挿入しておけばいいのでは?

TextMeshProから改行位置の情報を取得したい

きっとどこかに、改行位置の情報があるに違いないと思い探したらありました。
https://docs.unity3d.com/ja/Packages/com.unity.textmeshpro@3.0/api/TMPro.TMP_LineInfo.html

 TextMeshProUGUI.textInfo.lineInfo

 // 行の最初の文字のindex
 lineInfo.firstVisibleCharacterIndex
 // その行に何文字表示されるか
 lineInfo.characterCount

改行位置を取得して、改行コードを挿入してみる

// TextMeshProに文字列をセットして、自動改行の位置を計算してもらう
textMeshProUGUI.text = srcText;
// 改行コードを挿入する
var lineInfo = textMeshProUGUI.textInfo.lineInfo;
string text = string.Empty;
foreach (var info in lineInfo) {
   if (info.visibleCharacterCount > 0) {
       text += textMeshProUGUI.text.Substring(info.firstVisibleCharacterIndex, info.visibleCharacterCount) + "\n";
   }
}

結果

スクリーンショット 2024-01-29 18.07.01.png

取得はできたが、情報が間違っている

情報の取得はできたが、値が期待してたものと違いました。
lineInfoはTextMeshProにテキストをセットした瞬間に計算されるわけではなく
TextMeshProのUpdateの中で計算されるようで
セットしたフレームに取りに行った情報は、古い情報だったようです。

1フレーム待ってみる。

// TextMeshProに文字列をセットして、自動改行の位置を計算してもらう
textMeshProUGUI.text = srcText;
// 自動改行の計算のため1フレーム待つ
await UniTask.DelayFrame(1);
// 改行コードを挿入する
var lineInfo = textMeshProUGUI.textInfo.lineInfo;
string text = string.Empty;
foreach (var info in lineInfo) {
   if (info.visibleCharacterCount > 0) {
       text += textMeshProUGUI.text.Substring(info.firstVisibleCharacterIndex, info.visibleCharacterCount) + "\n";
   }
}

できた!

6e6e8778d7e3fe3c4745a011d34718cf.gif

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1