search
LoginSignup
21
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

環境

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;
    }
}

Animator.gif

解説

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

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】

アニメーションのアセット。
スクリーンショット 2017-08-06 17.58.36.png

【Animation】

シーン内のゲームオブジェクトとAnimationClipを紐付けるコンポーネント。
スクリーンショット 2017-08-06 18.22.33.png

【Animator Controller】

1つ以上のAnimationClipへの参照を持っており、ステートマシンを使用して遷移を管理するアセット。
スクリーンショット 2017-08-06 17.58.46.png

【Animator】

シーン内のゲームオブジェクトとAnimator Controllerを紐付けるコンポーネント。
スクリーンショット 2017-08-06 18.22.06.png

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でできることもまとめておきたいです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
21
Help us understand the problem. What are the problem?