腕組しながら語る
話題のエルデンリングについて、その面白さよりも騎馬戦や召喚魔法等の救済措置の多さを取り上げて「SEKIROに比べるとフロムも随分丸くなったなぁ」とか気持ち悪い感想をつぶやいてる皆さんこんにちは。
とにかく今作はボリュームがありすぎて、15時間プレイしても未だ噂のマルギットさんとお会いしてません。ちょっと歩くと中ボスやらドラゴンやらダンジョンがあるし。
DOTweenTMPAnimator
みんな大好きDOTweenのPro版にはTextMeshに対するTweenのメソッドが用意されています。
それらはText全体に対するアニメ動作を実装するものと、Textを1文字ずつ個別にアニメーションさせるものがあります。
Textを1文字ずつ個別に動作させる場合はDOTweenTMPAnimatorクラスを使用しますが、これはTextMeshをラップしたDOTweenTMPAnimatorクラスを生成し、それに対してTweenを行う方式で実装します。
現在作成中の「W.T.」でもこのクラスを利用して下の動画のようなテキストアニメーションを実装しています。
一文字ずつ左に移動させながらフェードアウトするアニメ
ソースはこんな感じ
DOTweenTMPAnimator textAnim2 = new DOTweenTMPAnimator(MyTextMesh); for (int iCnt = 0; iCnt < textAnim2.textInfo.characterCount; iCnt++) { textAnim2.DOOffsetChar(iCnt, Vector3.left * 30.0f, 1.5f).SetDelay(0.1f * iCnt); textAnim2.DOFadeChar(iCnt, 0, 2.5f).SetDelay(0.1f * iCnt); }
問題点
上述のように非常に便利なDOTweenTMPAnimatorクラスですが、同じTextMeshに対して文字列を入れ替えてテキストアニメーションさせようとした場合、
当然ながらその度にDOTweenTMPAnimatorクラスを再生成(new)する必要があります。
この場合、数回なら問題ないのですが、それ以上になるとテキストアニメーションの開始に遅延が発生し、下手するとゲーム全体が一時停止したような状態になります。
表示するテキスト毎にそれぞれTextMeshを定義すれば大丈夫なのでしょうが、そうすると1シーン内に大量にTextMeshが必要になったりしてあまり現実的な対応ではありません。
解決法
色々試した結果、以下の二点の対応を行うと解消されることが分かりました。
- DOTweenTMPAnimatorクラスをメンバ変数として使いまわす。
- Tweenが完了したらDOTweenTMPAnimatorクラスのResetメソッドをコールする。
特にDOTweenTMPAnimatorクラスをメンバ変数として使いまわす事は重要で、一つの関数内のローカル変数として毎度生成させていると3,4回目ぐらいで激重状態になります。
また、DOTweenTMPAnimatorクラスでも完了時のコールバックは指定可能なので、最後の文字のTweenが完了したらResetメソッドをコールするようにしましょう。
対処後のソース
DOTweenTMPAnimator TextAnim; public void TextFadeColor() { for (int iCnt = 0; iCnt < TextAnim.textInfo.characterCount; iCnt++) { TextAnim.DOOffsetChar(iCnt, Vector3.left * 30.0f, 1.0f).SetDelay(0.1f * iCnt); if (iCnt == TextAnim.textInfo.characterCount - 1) { TextAnim.DOFadeChar(iCnt, 0, 1.5f).SetDelay(0.1f * iCnt).OnComplete(() => OnComplete_FadeOut()); } else { TextAnim.DOFadeChar(iCnt, 0, 1.5f).SetDelay(0.1f * iCnt); } } } public void OnComplete_FadeOut() { TextAnim.Reset(); }