【Unity】TextMeshProで文字単位で回転させるアニメーションを紹介する

どーも、ぐるたか@guru_takaです。

今回はTextMeshProを使って、文字を回転させてみます。完成形はこんな感じ!

さっそく、ソースと簡単な解説を紹介していきます。TextMeshProの導入方法、またアニメーションの仕組みについては下記記事を参考にしてみてください!
【Unity】TextMeshProを導入してみる【エラー対応・ 日本語フォント作成あり】【Unity】TextMeshProで文字アニメーションする方法をサンプルに沿って紹介する

GitHubにソースを載せています。
参考 gurutaka/TextMeshProSampleGitHub

ソース

まずはソースから!

RotateText.cs

using UnityEngine;
using TMPro;

public class RotateText : MonoBehaviour
{
    [SerializeField]
    private float animationSpeed = 1;
    [SerializeField]
    [Range(0, 360)] int maxRotation = 180;

    private TextMeshPro textMeshPro;
    private void Awake()
    {
        textMeshPro = gameObject.GetComponent();
    }

    // Update is called once per frame
    void Update()
    {
        // メッシュ更新
        textMeshPro.ForceMeshUpdate();

        var textInfo = textMeshPro.textInfo;
        if (textInfo.characterCount == 0)
        {
            return;
        }

        //文字毎にloop
        for (int index = 0; index < textInfo.characterCount; index++)
        {
            var charaInfo = textInfo.characterInfo[index];

            //ジオメトリない文字はスキップ
            if (!charaInfo.isVisible)
            {
                continue;
            }

            //Material参照しているindex取得
            int materialIndex = charaInfo.materialReferenceIndex;

            //頂点参照しているindex取得
            int vertexIndex = charaInfo.vertexIndex;

            //頂点(dest->destinationの略)
            Vector3[] destVertices = textInfo.meshInfo[materialIndex].vertices;

            float angle = maxRotation * Mathf.Sin(Time.time + 10 * index);

            Vector3 rotatedCenterVertex = (destVertices[vertexIndex + 1] + destVertices[vertexIndex + 2]) / 2;

            Vector3 offset = rotatedCenterVertex;
            destVertices[vertexIndex + 0] += -offset;
            destVertices[vertexIndex + 1] += -offset;
            destVertices[vertexIndex + 2] += -offset;
            destVertices[vertexIndex + 3] += -offset;


            //回転
            Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, angle), Vector3.one);

            destVertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(destVertices[vertexIndex + 0]);
            destVertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(destVertices[vertexIndex + 1]);
            destVertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(destVertices[vertexIndex + 2]);
            destVertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(destVertices[vertexIndex + 3]);

            destVertices[vertexIndex + 0] += offset;
            destVertices[vertexIndex + 1] += offset;
            destVertices[vertexIndex + 2] += offset;
            destVertices[vertexIndex + 3] += offset;
        }

        //ジオメトリ更新
        for (int i = 0; i < textInfo.meshInfo.Length; i++)
        {
            //メッシュ情報
            textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
            textMeshPro.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
        }
    }
}

回転の仕組み

回転処理を抜粋して解説します。

抜粋箇所

float angle = maxRotation * Mathf.Sin (Time.time + 10 * index);

//回転する
Vector3 rotatedCenterVertex = (destVertices[vertexIndex + 1] + destVertices[vertexIndex + 2]) / 2;

Vector3 offset = rotatedCenterVertex;
destVertices[vertexIndex + 0] += -offset;
destVertices[vertexIndex + 1] += -offset;
destVertices[vertexIndex + 2] += -offset;
destVertices[vertexIndex + 3] += -offset;

//回転
Matrix4x4 matrix = Matrix4x4.TRS (Vector3.zero, Quaternion.Euler (0, 0, angle), Vector3.one);

destVertices[vertexIndex + 0] = matrix.MultiplyPoint3x4 (destVertices[vertexIndex + 0]);
destVertices[vertexIndex + 1] = matrix.MultiplyPoint3x4 (destVertices[vertexIndex + 1]);
destVertices[vertexIndex + 2] = matrix.MultiplyPoint3x4 (destVertices[vertexIndex + 2]);
destVertices[vertexIndex + 3] = matrix.MultiplyPoint3x4 (destVertices[vertexIndex + 3]);

destVertices[vertexIndex + 0] += offset;
destVertices[vertexIndex + 1] += offset;
destVertices[vertexIndex + 2] += offset;
destVertices[vertexIndex + 3] += offset;

回転の中心は以下の図の通りです。文字の左上destVertices[vertexIndex + 1]と右上destVertices[vertexIndex + 2]の中心になります。

回転行列では、Matrix4x4.TRSを使っています。


public Vector3 translation;//平行移動
public Vector3 eulerAngles;//回転
public Vector3 scale = new Vector3(1, 1, 1);//スケール

Matrix4x4 m = Matrix4x4.TRS(translation, rotation, scale);
参考 Matrix4x4 | スクリプトレファレンスUnity 公式 参考 Matrix4x4.TRS<br /> Unity 公式

offset(回転の中心点)分を現在の位置からズラしてから回転。その後に、offset(回転の中心点)分、位置を戻せば完成です!

offset分ズラさないと、ある点を中心に文字全体が回転しちゃうので注意してください!

最後に

以上になります。前回に紹介した平行移動と今回の回転を組み合わせれば、幅広い演出ができそうです。

ぜひ参考にしてみてください!

参考リンク

参考 TextMesh Pro - Animating Vertex PositionsYoutube

コメントを残す