原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】繰り返し使うと重くなるDOTweenTMPAnimatorへの対処

f:id:Karvan:20220301202656p:plain

腕組しながら語る

話題のエルデンリングについて、その面白さよりも騎馬戦や召喚魔法等の救済措置の多さを取り上げて「SEKIROに比べるとフロムも随分丸くなったなぁ」とか気持ち悪い感想をつぶやいてる皆さんこんにちは。
とにかく今作はボリュームがありすぎて、15時間プレイしても未だ噂のマルギットさんとお会いしてません。ちょっと歩くと中ボスやらドラゴンやらダンジョンがあるし。

 

DOTweenTMPAnimator

みんな大好きDOTweenのPro版にはTextMeshに対するTweenのメソッドが用意されています。
それらはText全体に対するアニメ動作を実装するものと、Textを1文字ずつ個別にアニメーションさせるものがあります。

Textを1文字ずつ個別に動作させる場合はDOTweenTMPAnimatorクラスを使用しますが、これはTextMeshをラップしたDOTweenTMPAnimatorクラスを生成し、それに対してTweenを行う方式で実装します。

現在作成中の「W.T.」でもこのクラスを利用して下の動画のようなテキストアニメーションを実装しています。

f:id:Karvan:20220228000244g:plain

一文字ずつ左に移動させながらフェードアウトするアニメ
ソースはこんな感じ

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)する必要があります。

f:id:Karvan:20220301203704g:plain

この場合、数回なら問題ないのですが、それ以上になるとテキストアニメーションの開始に遅延が発生し、下手するとゲーム全体が一時停止したような状態になります
表示するテキスト毎にそれぞれ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();
}

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。