Edited at

Animatorの動的attachと停止、再生の制御

More than 1 year has passed since last update.


環境

Unity 5.3.7p4

使用アセット:Sprite Pack #1 - Tap and Fly

https://www.assetstore.unity3d.com/jp/#!/content/21454


はじめに


やりたいこと

・動的にAnimatorコンポーネントをattachする

・任意のタイミングで再生する

・任意のタイミングでアニメーションの1フレーム目に戻す


つまづいたこと

・Animator?AnimatorController?Animation?AnimationClip?似たようなのが多いぞ!

・AnimatorはStopで止まるけどPlayで再開しない...

・1フレーム目の状態に初期化するっていう指定できないの?


先にまとめ

using UnityEngine;

public class AnimationContorller : MonoBehaviour {

// プレイヤーオブジェクト
[SerializeField]
GameObject m_playerObj;

// プレイヤーのアニメーターコンポーネント
Animator m_playerAnimaor;
// animatorのstate名
const string MOVE_ANIM_NAME = "move";
// アニメーションの開始時間
float m_animStartTime;
// プレイヤーの初期位置
Vector3 m_startPos;
// 鳥のSpriteRenderer
SpriteRenderer m_sprite;
// 鳥のSpriteRendererのXの向き
bool m_xFlip;

// Use this for initialization
void Start () {
// Animatorコンポーネントをaddし、AnimatorControllerをセットする
m_playerAnimaor = m_playerObj.AddComponent<Animator>();
m_playerAnimaor.runtimeAnimatorController = Resources.Load<RuntimeAnimatorController>("Animation/Player");
m_playerAnimaor.enabled = false;

// 巻き戻し用に記憶
m_startPos = m_playerObj.transform.localPosition;
m_sprite = m_playerObj.transform.Find("Bird").GetComponent<SpriteRenderer>();
m_xFlip = m_sprite.flipX;
}

/// <summary>
/// 再生ボタンタップ
/// </summary>
public void Play(){
// 再生中なら返す
if (m_playerAnimaor.enabled) {
return;
}
m_playerAnimaor.enabled = true;
m_playerAnimaor.Play(MOVE_ANIM_NAME, 0, m_animStartTime);
}

/// <summary>
/// ポーズボタンタップ
/// </summary>
public void Pause(){
m_playerAnimaor.enabled = false;
m_animStartTime = m_playerAnimaor.GetCurrentAnimatorStateInfo(0).normalizedTime;
}

/// <summary>
/// 巻き戻しボタンタップ
/// </summary>
public void Rewind(){
m_playerAnimaor.enabled = false;
m_animStartTime = 0f;
m_playerAnimaor.transform.localPosition = m_startPos;
m_sprite.flipX = m_xFlip;
}
}


解説


アニメーション周りのクラスをざっくり整理

AnimationClipとAnimationで1セット。Animator ControllerとAnimatorで1セット。単純にアニメーションを再生したいだけならAnimationClipとAnimationだけで可能。ステート管理や時間の指定など、複雑なことをしたいならAnimator ControllerとAnimatorを使用するイメージ。

Animation単体で再生したいときはAnimationClipをLegacyにする必要があります。(8/7 追記:記述忘れmm)

▽Animatorを使わずにAnimation単体で再生する

http://kazuooooo.hatenablog.com/entry/2015/08/02/192754


【AnimationClip】

アニメーションのアセット。


【Animation】

シーン内のゲームオブジェクトとAnimationClipを紐付けるコンポーネント。


【Animator Controller】

1つ以上のAnimationClipへの参照を持っており、ステートマシンを使用して遷移を管理するアセット。


【Animator】

シーン内のゲームオブジェクトとAnimator Controllerを紐付けるコンポーネント。


Animatorを動的にattachする

m_playerAnimaor = m_playerObj.AddComponent<Animator>();

m_playerAnimaor.runtimeAnimatorController = Resources.Load<RuntimeAnimatorController>("Animation/Player");

AddComponentはそのままAnimatorなんですが、AnimationControllerはruntimeAnimatorControllerで指定しないと駄目でした。

▽UnityでAnimationControllerをscriptから指定する

http://qiita.com/hakuta/items/7208576a1af399dc8a65


アニメーション開始の時間

m_playerAnimaor.Play(MOVE_ANIM_NAME, 0, m_animStartTime);

Animator.Playの引数で開始時間を指定することができます。

Pause時に記録しておいたものを設定すれば止めた続きから再生できます。

m_animStartTime = m_playerAnimaor.GetCurrentAnimatorStateInfo(0).normalizedTime;


アニメーションの初期化

色々調べたのですが最初のフレームの状態にする方法は分かりませんでした。

結局、Start時に記録しておいた情報を元に巻き戻し時に位置と画像の向きを初期化をしています。


さいごに

一旦頭の中が整理できました。

AnimatorStateInfoやAnimatorClipInfoでできることもまとめておきたいです。