メッセージを1文字ずつ表示するウィンドウを作っていたら、前の行の文字が突然次の行に移動した
原因
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";
}
}
結果
取得はできたが、情報が間違っている
情報の取得はできたが、値が期待してたものと違いました。
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";
}
}