FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »2020年02月
2020年02月の記事一覧

【Unity】【C#】現在再生中のアニメーションの経過時間を取得する  


 なぜかググっても簡単な例が見つからなかったので、とりあえずのものを書いておく。長さの取得例は多いんだけどね。基本的には AnimatorStateInfoAnimationState あたりで取得できる情報を使えば良いだけなのだが、毎回書くのは面倒だったので、拡張メソッドを定義しておくと楽になると思う。


(※) Unity 2019.2.20f1 / Windows10(x64) で確認



■Animator から経過時間/長さを取得

●Animator から経過時間/長さを取得
using UnityEngine;

public static class Extensions //※名前は任意
{
/// <summary>
/// 現在のアニメーションの経過時間を取得する
/// </summary>
/// <param name="animator">対象のアニメータ</param>
/// <param name="layerIndex">レイヤーのインデクス</param>
/// <returns>経過時間(秒), null のときは常に 0</returns>
public static float GetCurrentTime(this Animator animator, int layerIndex = 0)
{
if (animator == null)
return 0;

AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(layerIndex); //現在のステートを取得
return stateInfo.length * stateInfo.normalizedTime;
}

/// <summary>
/// 現在のアニメーションの長さを取得する
/// </summary>
/// <param name="animator">対象のアニメータ</param>
/// <param name="layerIndex">レイヤーのインデクス</param>
/// <returns>アニメーションの長さ(秒), null のときは常に 0</returns>
public static float GetLength(this Animator animator, int layerIndex = 0)
{
if (animator == null)
return 0;

AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(layerIndex); //現在のステートを取得
return stateInfo.length;
}
}

●使用例(メインコード等)
using UnityEngine;

var animator = GetComponent<Animator>();
Debug.Log("time = " + animator.GetCurrentTime()); //※アクセスしているアニメーションが動いている方がわかりやすい
Debug.Log("length = " + animator.GetLength());

 GetLength() の方はついでに作っておいただけのものなので、実際には同時に取得したいなら、普通に AnimatorStateInfo 取得してプロパティを使った方が良いかも知れない。特に長さは途中で変わるものではないから、使い回すときには結果をキャッシュした方が良いこともあるね。

AnimatorStateInfo



■Animation から経過時間/長さを取得

●Animation から経過時間/長さを取得
using UnityEngine;

public static class Extensions //※名前は任意
{
/// <summary>
/// 現在のアニメーションの経過時間を取得する
/// </summary>
/// <param name="animation">対象のアニメーション</param>
/// <param name="allowWrapMode">ラップモードに従う:true = 永久ループ系(Loop, PingPong)のとき長さ以上も許可 / false = 曲の長さ以内</param>
/// <returns>経過時間(秒), null のときは常に 0</returns>
public static float GetCurrentTime(this Animation animation, bool allowWrapMode = false)
{
if (animation == null || animation.clip == null)
return 0;

AnimationState state = animation[animation.clip.name]; //現在のステートを取得
//WrapMode が永久ループ系(Loop, PingPong)のとき、長さ(length)より大きくなることもある
//https://docs.unity3d.com/ja/current/ScriptReference/WrapMode.html
//また、再生速度のプロパティ:speed は1(1倍)で考えているが、1でないときは time は現実時間とは違うので注意(長さに対する位置と考えるとわかりやすい)
return allowWrapMode ? state.time : (state.time % state.length);
}


/// <summary>
/// 現在のアニメーションの長さを取得する
/// </summary>
/// <param name="animation">対象のアニメーション</param>
/// <returns>アニメーションの長さ(秒), null のときは常に 0</returns>
public static float GetLength(this Animation animation)
{
if (animation == null || animation.clip == null)
return 0;

return animation.clip.length;
}
}

●使用例(メインコード等)
using UnityEngine;

var animation = GetComponent<Animation>();
Debug.Log("time = " + animation.GetCurrentTime()); //※アクセスしているアニメーションが動いている方がわかりやすい
Debug.Log("length = " + animation.GetLength());

 GetLength() の方はついでに作っておいただけのものなので、実際には同時に取得したいなら、普通に AnimationState 取得してプロパティを使った方が良いかも知れない。特に長さはステートからでも clip プロパティ(AnimationClip) からも取得できるのでメソッド無くても良いしね(まぁ、Animator のと同じように統一して定義しておくと、迷わなくて済むというだけ(笑))。

 AnimationState にも AnimatorStateInfo のように正規化された時間(曲の長さを1とし、0~1で位置を表す):normalizedTime があるので、「state.length * state.normalizedTime」でも経過時間を求められる。必要あればその方法で計算をするのも良いだろう(この例では別段必要はないので time の方にした)。

AnimationState


 また、ここではアニメーションの再生速度のプロパティ:speed は1(=1倍)で考えているが、1でないときは time は現実時間とは違うので注意しよう(長さに対する位置と考えるとわかりやすい)。その場合、現実時間は以下のようにすれば求まる。

●speed が1以外のとき、現実の時間を求める
var animation = GetComponent<Animation>();
AnimationState state = animation[animation.clip.name];
float realTime = (1f / state.speed) * state.time;

 再生速度に関わらず現実時間に合わせたいなら「state.speed * state.time」で良い。まぁ、このような比率的な計算をするなら normalizedTime を使った方が直感的に書けるというメリットがある。用途に合わせて使い分けると良いだろう。







(関連記事)
【Unity】AnimationCurve をコードで初期化する
【Unity】5.6 のアニメーションは非アクティブ化でリセットされない(5.6のアニメーション挙動の違い)


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  Unityリファレンス 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR