この記事は Unity アセット真夏のアドベントカレンダー 2021 Summer! 19日目の記事です。
テキストアニメーション系アセットとDOTweenPro
最近自分の周りで、テキストアニメーション系アセットの話題をよく耳にします。
よく聞くアセットは以下の2つ。
自分はこの2つのアセットを持っていないのですが、既に持っているDOTween Proというアセットでも同じようなことできるのでは?と思い、試してみました。
DOTween Proというのはテキストに限らず、いろんなものをアニメーションさせることのできるアセットです。
無料版の「DOTween」と有料版の「DOTween Pro」がありますが、この記事で紹介するテキストアニメーションはDOTween Proでのみ利用できる機能を多く使っています。
無料版ではTextMeshProのアニメーションや、一文字ごとに細かくアニメーションを指定することなどができないので注意。
今回DOTweenProで作成したテキストアニメーション
今回作成したテキストアニメーションをまとめたものがこちら。
GitHubで公開しました。
https://github.com/Yusuke57/DOTweenTextAnimation
解説
数が多いので、いくつかのテキストアニメーション例を解説します。
それ以外はGitHubにあげたものを参考にしていただけますと幸いです。
DOTweenの公式ドキュメントも是非参考に!
ノベルゲームのような文章表示
まずはシンプルな、ノベルゲームやADVでよくある文章表示。
これはかなり簡単に実現できます。
using DG.Tweening;
using TMPro;
using UnityEngine;
public class NovelAnimationText : MonoBehaviour
{
private TextMeshProUGUI textMeshPro;
private void Awake()
{
textMeshPro = GetComponent<TextMeshProUGUI>();
Initialize();
Play(2.5f);
}
private void Initialize()
{
textMeshPro.text = string.Empty;
}
private void Play(float duration)
{
var text = "ノベルゲームのような文章表示";
textMeshPro.DOText(text, duration).SetEase(Ease.Linear);
}
}
DOText
メソッドを使うことで、1文字ずつ表示することができます。
ちなみに無料版でもuGUI標準のTextコンポーネントであれば、このDOText
に関しては利用可能。TextMeshProを使うためには有料版が必要です。
また、DOText
の引数を追加することで、サイバー感のあるテキスト表示もできます。
第3引数はリッチテキストを許容するか否かを指定し、第4引数にテキストが表示されるまでにランダム表示しておく文字タイプを指定します。
今回の場合は大文字アルファベットを指す ScrambleMode.Uppercase
を指定しました。
textMeshPro.DOText(text, duration, false, ScrambleMode.Uppercase).SetEase(Ease.Linear);
各文字を交互にアニメーション
DOTweenProで使えるDOTweenTMPAnimatorでは、TextMeshProの各文字それぞれに対してアニメーションを設定することができます。(無料版では使えません)
今回は偶数番目の文字と奇数番目の文字に分けて少し異なるアニメーションを設定しました。
using DG.Tweening;
using TMPro;
using UnityEngine;
public class ZigzagCharAnimationText : MonoBehaviour
{
private DOTweenTMPAnimator tmpAnimator;
private void Awake()
{
var textMeshPro = GetComponent<TextMeshProUGUI>();
tmpAnimator = new DOTweenTMPAnimator(textMeshPro);
Initialize();
Play(2.5f);
}
private void Initialize()
{
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
tmpAnimator.DOOffsetChar(i, Vector3.zero, 0);
// 偶数番目の文字は黄色、奇数番目の文字は青色
var color = i % 2 == 0 ? new Color(1, 0.8f, 0.3f) : new Color(0.3f, 0.7f, 1);
tmpAnimator.DOColorChar(i, color, 0); // 秒数に0を指定することで瞬時に変更
}
}
private void Play(float duration)
{
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
// 偶数番目と奇数番目で方向を変える
var sign = Mathf.Sign(i % 2 - 0.5f);
DOTween.Sequence()
.Append(tmpAnimator.DOOffsetChar(i, Vector3.up * 100 * sign, duration / 2).SetEase(Ease.OutFlash, 2))
.Append(tmpAnimator.DOOffsetChar(i, Vector3.down * 100 * sign, duration / 2).SetEase(Ease.OutFlash, 2));
}
}
}
DOTweenTMPAnimatorで一文字ごとにアニメーションさせる場合、大体以下のように指定します。
tmpAnimator.DOXXXXChar([対象の文字のインデックス(0から初めて何文字目か)], 目的の値, 秒数);
また、 全体の文字数は tmpAnimator.textInfo.characterCount
で取得できるので、こちらもfor文の条件としてよく利用します。
Ease.Flash
系のイージングは反復するような動きをするもので、SetEase
メソッドの第二引数に反復回数を指定します。SetEase(Ease.OutFlash, 2)
のように「2」を指定することで、1往復のアニメーションとなります。
文字間隔を広げていくアニメーション
簡単でカッコいいので、個人的にとても好きなテキストアニメーションです。
using DG.Tweening;
using TMPro;
using UnityEngine;
public class CharSpaceAnimationText : MonoBehaviour
{
private TextMeshProUGUI textMeshPro;
private void Awake()
{
textMeshPro = GetComponent<TextMeshProUGUI>();
Initialize();
Play(2.5f);
}
private void Initialize()
{
textMeshPro.DOFade(0, 0);
textMeshPro.characterSpacing = -50;
}
private void Play(float duration)
{
// 文字間隔を開ける
DOTween.To(() => textMeshPro.characterSpacing, value => textMeshPro.characterSpacing = value, 10, duration)
.SetEase(Ease.OutQuart);
// フェード
DOTween.Sequence()
.Append(textMeshPro.DOFade(1, duration / 4))
.AppendInterval(duration / 2)
.Append(textMeshPro.DOFade(0, duration / 4));
}
}
今回は文字間隔を開けるアニメーションと、フェードするアニメーションの2つに分けて実装しました。
TextMeshProの文字間隔をアニメーションさせるための拡張メソッドはDOTweenProにも用意されていないので、DOTween.To
メソッドを使って文字間隔をアニメーションさせています。
テキストアニメーション応用編
最後に、テキストアニメーションの応用編を1つ解説します。
DOTweenTMPAnimatorを使って、左側の文字から順にアニメーションさせています。
幅広い応用が効くので、基本の作り方さえ覚えていればかなり役立つはず。
using DG.Tweening;
using TMPro;
using UnityEngine;
public class AnimationText6 : MonoBehaviour
{
private DOTweenTMPAnimator tmpAnimator;
private void Awake()
{
var textMeshPro = GetComponent<TextMeshProUGUI>();
tmpAnimator = new DOTweenTMPAnimator(textMeshPro);
Initialize();
Play(2.5f);
}
private void Initialize()
{
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
tmpAnimator.DORotateChar(i, Vector3.right * 90, 0);
tmpAnimator.DOOffsetChar(i, Vector3.zero, 0);
tmpAnimator.DOFadeChar(i, 1, 0);
}
}
private void Play(float duration)
{
const float EACH_DELAY_RATIO = 0.01f;
var eachDelay = duration * EACH_DELAY_RATIO;
var eachDuration = duration - eachDelay;
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
DOTween.Sequence()
.Append(tmpAnimator.DORotateChar(i, Vector3.right * 360, eachDuration / 2, RotateMode.FastBeyond360))
.AppendInterval(eachDuration / 4)
.Append(tmpAnimator.DOOffsetChar(i, Vector3.down * 40f, eachDuration / 4))
.Join(tmpAnimator.DOFadeChar(i, 0, eachDuration / 4))
.SetDelay(eachDelay * i);
}
}
}
一文字ごとにアニメーションさせ、それぞれ少しずつアニメーション開始時間を遅らせています。
const float EACH_DELAY_RATIO = 0.01f;
var eachDelay = duration * EACH_DELAY_RATIO;
var eachDuration = duration - eachDelay;
ここら辺がちょっとごちゃごちゃしていますが、要はアニメーション全体をduration
秒で終わらせたいという目的があり、それに合うように一文字ごとの開始時間の遅れとアニメーション時間を計算しています。
一文字ずつそれぞれSequence
を使ってアニメーションを指定しています。
「文字の回転」→「待機」→「下に動く & フェードアウト」というアニメーションを、eachDelay * i
秒ずつズラしながら再生。
まとめ
DOTweenは無料版でも十分魅力的なアセットなのですが、有料版であるDOTweenProにはさらに魅力的な機能が使えます。
まだDOTweenProを持っていない方、特にテキストアニメーションを簡単に作りたい方は是非、DOTweenProをご検討ください!そもそも比較的安価なアセットですが、実際できることを加味すれば圧倒的にコスパの良いアセットだと自分は思います。
また、DOTweenProを既に持っている方も結構いらっしゃるかと思います。
テキストアニメーションはあまり使っていないという方は、是非一度試してみてはいかがでしょうか。
今回の記事はテキストアニメーション系のアセットを見て、DOTweenProではどのくらいテキストアニメーションできるのかな?というところが動機でした。
もちろんテキストアニメーション系アセットにはDOTweenProにはない魅力的なメリットがあるだろうと思っていますが、自分はまだまだDOTweenProを使っていきたいと思っています!
コメント