この記事は何?
RPG等でダメージを与えた(くらった)時に、頭の上に数字が出てくるタイプのダメージ表現をUnityで実装するまでの備忘録です
環境
- Unity - 2020.3.16f1 (LTS)
- DOTween Pro - Version 1.0.310
- TextMeshPro - Version 3.0.6
※DOTweenには無料版もありますが、TextMeshProと組み合わせて使うので、DOTween Proが必要になります(令和3年8月16日現在)
準備
まずは、DOTweenでTextMeshProを使用するための設定を行う必要があります
以下の手順でDOTweenの設定を行います
1 : Tools > Demigiant > DOTween Utility Panel でDOTweenのユーティリティを開く
2 : Setup DOTween...(add/remove Modules) ボタン押下で設定画面を開く
3 : DOTween Pro / DOTween Timelineの中にあるTextMesh Proにチェックをする
4 : Applyを押して設定を反映させたら完了です
実装内容
基本
TextMeshProをアニメーションさせるためには、DOTweenTMPAnimatorを使用します
TextMeshProUGUI textMeshProUGUI = GetComponent<TextMeshProUGUI>();
DOTweenTMPAnimator tmpAnimator = new DOTweenTMPAnimator(textMeshProUGUI);
アニメーション
複数のアニメーションを組み合わせて作っていきます
登場
テキストが登場するまでのアニメーションには、3つのアニメーションを組み合わせています
DOOffsetChar(int charIndex, Vector3 endValue, float duration)
1文字ごと個別に移動させます。
TextMeshProUGUI textMeshProUGUI = GetComponent<TextMeshProUGUI>();
DOTweenTMPAnimator tmpAnimator = new DOTweenTMPAnimator(textMeshProUGUI);
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
var charOffset = tmpAnimator.GetCharOffset(i);
// 1秒かけて今いる位置からyが+5の位置に移動する
tmpAnimator.DOOffsetChar(i, charOffset - new Vector3(0f, 5f, 0f), 1f);
}
DOFadeChar(int charIndex, float endValue, float duration)
1文字ごと個別に透明度(アルファ値)を変更します
TextMeshProUGUI textMeshProUGUI = GetComponent<TextMeshProUGUI>();
DOTweenTMPAnimator tmpAnimator = new DOTweenTMPAnimator(textMeshProUGUI);
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
// 3秒かけてalphaを1にする(0.0f~1.0f)
tmpAnimator.DOFadeChar(i, 1f, 3f);
}
DOScaleChar(int charIndex, float endValue, float duration)
1文字ごと個別に大きさを変更します
TextMeshProUGUI textMeshProUGUI = GetComponent<TextMeshProUGUI>();
DOTweenTMPAnimator tmpAnimator = new DOTweenTMPAnimator(textMeshProUGUI);
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
// 2秒かけて大きさを3fにする(x:3 y:3 z:3)
tmpAnimator.DOScaleChar(i, 3f, 2f);
}
消滅
登場の際に使用したDOOffsetCharとDOFadeCharを使用しています
DoOffsetCharで上へ移動し、DoFadeCharでアルファ値を0にしています。
アニメーションの組み合わせ
登場と消滅のアニメーションはDOTweenのSequenceを使用し、繋げて再生されるようにしています
Sequenceについて詳しくは👇
- [Unity] DOTweenのSequenceを使ってアニメーションを結合する
完成
スクリプト
今回作成したスクリプト全文
using DG.Tweening;
using TMPro;
using UnityEngine;
public class DamagePopupTextAnimator : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI textMeshProUGUI;
[SerializeField] private float textAppearDuration = 0.15f;
[SerializeField] private float textDisappearDuration = 0.3f;
[SerializeField] private float textJumpHeight = 30f;
private void Start()
{
textMeshProUGUI.text = string.Empty;
textMeshProUGUI.DOFade(0, 0);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
TakeDamage(Random.Range(1, 10000));
}
}
private void TakeDamage(int damage)
{
textMeshProUGUI.DOFade(0, 0);
textMeshProUGUI.text = damage.ToString();
var tmpAnimator = new DOTweenTMPAnimator(textMeshProUGUI);
for (var i = 0; i < tmpAnimator.textInfo.characterCount; i++)
{
tmpAnimator.DOScaleChar(i, 0.7f, 0);
var charOffset = tmpAnimator.GetCharOffset(i);
var sequence = DOTween.Sequence();
// 登場
sequence.Append(tmpAnimator.DOOffsetChar(i, charOffset + new Vector3(0f, textJumpHeight, 0f), textAppearDuration)
.SetEase(Ease.OutFlash, 2))
.Join(tmpAnimator.DOFadeChar(i, 1f, textAppearDuration/2f))
.Join(tmpAnimator.DOScaleChar(i, 1f, textAppearDuration)
.SetEase(Ease.OutBack))
.SetDelay(0.05f * i);
// タイミングを合わせて0.5秒待つ
sequence.AppendInterval(0.05f * (tmpAnimator.textInfo.characterCount - i))
.AppendInterval(0.5f);
// 消滅
sequence.Append(tmpAnimator.DOFadeChar(i, 0, textDisappearDuration));
sequence.Join(tmpAnimator.DOOffsetChar(i, charOffset + new Vector3(0, textJumpHeight, 0), textDisappearDuration)
.SetEase(Ease.Linear));
}
}
}
おわりに
他にも色々なDO〇〇Char関数が有るので、様々なダメージポップアップテキストのアニメーションを作成できそうですね
- DOTween - Documentation
参考サイト
- DOTweenでTextMeshProを文字ごとにアニメーションさせる
- DOTween公式
- Unity Asset Store - DOTween Pro
- TextMeshPro
- [Unity] DOTweenのSequenceを使ってアニメーションを結合する
ライセンス
この記事はユニティちゃんライセンス条項の元に提供されています。