やりたいこと
- ムービープレーヤーのスライダーのような制御がしたい
- アニメ全長の任意の位置へジャンプしたいです。
- アニメの任意のフレームを再生したい
- シーケンシャルな再生でなく、任意のフレームに対してランダムにアクセスして、スクリプト制御で正逆任意の速度で再生したいです。
検証環境
- Unity 2019.4.x (LTS)
方法
Animator.Play (int stateNameHash, int layer, float normalizedTime)
を使います。stateNameHash
に0
を渡すと現在のステートになります。layer
に-1
を渡すと最初に一致したステートになります。normalizedTime
には、正規化された再生位置を渡します。- ループするアニメの場合は、
0f
と1f
で同じフレームが表示されます。- その場合は、
0.9999999f
とかにすれば最終フレームになります。
- その場合は、
- ループするアニメの場合は、
- なお…
具体例
以下のコードでは、対象のスライダーとアニメーターが、コードがアタッチされたオブジェクトの子孫の何処かに存在することを前提にしています。
AnimeSlider.cs
usingUnityEngine;usingUnityEngine.UI;publicclassAnimeSlider:MonoBehaviour{privateSliderslider;privateAnimatoranimator;/// <summary>初期化</summary>voidStart(){slider=GetComponentInChildren<Slider>();slider.onValueChanged.AddListener(OnChangeSlider);animator=GetComponentInChildren<Animator>();animator.speed=0;// 再生をポーズ}/// <summary>スライダが変化</summary>publicvoidOnChangeSlider(float_){animator.Play(0,-1,slider.normalizedValue);}}
- これによって、スライダーの位置に応じた任意のフレームが再生されます。
- ループするアニメの場合は、スライダの左端と右端で同じフレームが表示されます。
- 同じにしたくない場合は、
slider.normalizedValue * 0.9999999f
とかにします。
- 同じにしたくない場合は、
- ポーズを解除する場合は、
animator.speed = 1;
します。
蛇足
複数の同じアニメを時間差で表示
AnimeSlider.csusingUnityEngine;usingUnityEngine.UI;publicclassAnimeSlider:MonoBehaviour{privateSliderslider;privateAnimator[]animators;/// <summary>初期化</summary>voidStart(){slider=GetComponentInChildren<Slider>();slider.onValueChanged.AddListener(OnChangeSlider);animators=GetComponentsInChildren<Animator>();foreach(varanimatorinanimators){animator.speed=0;// 再生をポーズ}}/// <summary>スライダが変化</summary>publicvoidOnChangeSlider(float_){for(vari=0;i<animators.Length;i++){vartime=slider.normalizedValue-((float)i/animators.Length);if(time<0f){time+=1f;}animators[i].Play(0,-1,time);}}}