【Unity】normalizedTimeとは?アニメーションの再生位置を表す変数

normalizedTimeとは? Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「UnityのnormalizedTimeってなに?」

「normalizedTimeの使い方が知りたい!」

というお悩みの方に向けた内容となっています。

Unityでアニメーションを再生する際、よく使われる変数としてnormalizedTimeがあります。

normalizedTimeとは、アニメーションの再生位置を正規化している変数で、スタート地点を0、終了地点を1として再生位置に応じて変動した値を取得することができます。

このnormalizedTimeを使うことで、アニメーションが現在再生されている位置や最後まで再生されたかどうかなどを判定することができます。

そこで、このページでは、UnityのnormalizedTimeという変数について、どんな変数なのか、使い方や実際の使用例までをまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

normalizedTimeとは?アニメーションの再生位置を正規化した変数

normalizedTimeという変数は、アニメーションの再生位置を正規化した値で取得できるAnimatorStateInfoクラスで定義されている変数です。

もう少し詳しく説明すると、アニメーションの全体の長さを1とした場合に、開始地点を0、終了地点を1として、アニメーションが再生されている位置をfloat型の数値で取得することができる変数です。

例えば、アニメーションの真ん中の位置が再生されているときは、normalizedTimeの値は0.5となります。

また、アニメーションがループされた場合は1以上となり、ループされる度に整数部分の値が増えていくことになります。

そして、このnormalizedTimeでアニメーションの再生位置を取得することで、アニメーションが最後まで再生されているかを判定したり、ループ回数による処理を実装するなど、様々なアニメーションの処理で使うことができます。

normalizedTimeの使い方

ここからは、normalizedTimeの変数の使い方について紹介していきます。

normalizedTimeを取得する

normalizedTimeは、以下のように記述することで、その時点での再生位置の値をfloat型で取得することができます。

AnimatorStateInfo.normalizedTime

normalizedTimeを使用する際は、どのアニメーションの値を取得するか、前の部分でアニメーションステート(AnimatorStateInfo)を指定します。

アニメーションステートとは、AnimatorControllerの中でアニメーションが紐付いている以下の項目の部分を指しています。

このアニメーションステートを指定する場合によく使うのが、Animatorコンポーネントで定義されているGetCurrentAnimatorStateInfoメソッドです。

Animator.GetCurrentAnimatorStateInfo(レイヤー番号)

GetCurrentAnimatorStateInfoメソッドは、現在再生中のアニメーションステートを取得できるメソッドで、上記のように引数にアニメーションのレイヤー番号を指定して使います。

アニメーションが最後まで再生されたかどうかを判定する

実際にnormalizedTimeを使って、アニメーションが最後まで再生されたかどうかを判定してみます。

ここでは、以下のようにオブジェクトが動く簡単なアニメーションを作成してみました。

アニメーションの作成については、以下の記事も参考にしてみてください。

なお、ループ再生はオフにしています。

このオブジェクトに対して、以下のスクリプトをアタッチしておきます。

using UnityEngine;

public class Test : MonoBehaviour
{
    Animator animator;
    SpriteRenderer spriteRenderer;

    void Start()
    {
        animator = GetComponent<Animator>();    // Animatorコンポーネントを取得する
        spriteRenderer = GetComponent<SpriteRenderer>();    // SpriteRendererコンポーネントを取得する
    }

    void Update()
    {
        // アニメーションの再生が終了した場合
        if (animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1)
        {
            spriteRenderer.color = Color.red;   // オブジェクトの色を赤色に変更する
        }
    }
}

まず、GetCurrentAnimatorStateInfoメソッドを使用するために、10行目のStartメソッドの中でGetComponentを使って、Animatorコンポーネントを取得しています。

次に17行目のif文の中で、現在再生されているアニメーションステートのnormalizedTimeの値が1以上かどうかを判定しています。

このnormalizedTimeの値が1以上になるということは、アニメーションが最後まで再生されたということになります。

そしてその中の19行目で、オブジェクトの色を白から赤に変更する処理を記述しています。

実際にゲームを実行してみると、

アニメーションの再生が終了したら、オブジェクトの色が変更されるようになりました。

アニメーションのループ回数を取得する

今度は、先ほどのアニメーションをループ再生するようにして、ループされた回数をnormalizedTimeで取得してみます。

スクリプトを以下のように修正します。

using UnityEngine;

public class Test : MonoBehaviour
{
    Animator animator;
    float preCount = 0;

    void Start()
    {
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        float loopCount = Mathf.Floor(animator.GetCurrentAnimatorStateInfo(0).normalizedTime);  // ループ回数を取得

        // ループ回数が更新された場合
        if (loopCount != preCount)
        {
            Debug.Log("ループ回数:" + loopCount + "回");
            preCount = loopCount;
        }
    }
}

15行目で、normalizedTimeで取得した値に対して、Mathf.Floorメソッドで小数点以下を切り捨てた値を、float型の変数に代入しています。

そして、20行目でこの変数の値が変動した際に、コンソールウィンドウにループ回数を表示させるようにしています。

これでゲームを実行してみると、

アニメーションのループ回数を取得して、表示されているのが分かります。

まとめ

このページでは、UnityのnormalizedTimeという変数について、どんな変数なのか、使い方までをまとめていきましたが、いかがでしたでしょうか?

normalizedTimeとは、アニメーションの再生している位置を取得することができる変数で、アニメーションの長さを1として再生位置をfloat型で取得します。

normalizedTimeを使う際は、GetCurrentAnimatorStateInfoメソッドなどで取得したアニメーションステートを指定して使います。

normalizedTimeを使うことで、アニメーションの再生位置に応じた処理を作ったり、ループ回数の制御を行うことができるようになります。

最後までお読みいただきまして、ありがとうございました!

コメント