本日は UniRx の小ネタ枠です。
ObservableStateMachineTriggerを使ってUniRxでアニメーションの終了を検知する手順を記事にします。
前回記事
以下の記事の続きになります。
bluebirdofoz.hatenablog.com
アニメーションの完了をトリガーで待機する
前回の ObservableStateMachineTrigger を応用してアニメーションの完了をトリガーで待機してみます。
トリガーで待機できればアニメーションのループの有無、ループ回数などをスクリプト側で制御できます。
AnimとAnimationControllerの設定
デフォルトではアニメーションをループさせるために、Anim の loop time にチェックを入れます。
またアニメーションの終了を命令後、アニメーションが即座に変化するように Transition からは[Has Exit Time]のチェックを外しておきます。
サンプルスクリプト
前回作成したスクリプトを以下の通り、改変しました。
シーンの再生と同時に LoopAction への遷移を開始し、LoopAction のアクションが2回ループしたら元のアニメーションに戻ります。
normalizedTime による終了監視は先に LoopAction への遷移が完了するのを待つ必要がある点に注意します。
・AnimationUniRxTest.cs
using System.Collections; using System.Collections.Generic; using System; using UnityEngine; using UniRx; using UniRx.Triggers; public class AnimationUniRxTest : MonoBehaviour { // Start is called before the first frame update void Start() { // Animatorコンポーネントの参照を取得 Animator animator = this.GetComponent<Animator>(); // AnimatorからObservableStateMachineTriggerの参照を取得 ObservableStateMachineTrigger trigger = animator.GetBehaviour<ObservableStateMachineTrigger>(); // LoopActionに遷移する animator.SetBool("ActionFlg", true); // 遷移したアニメーションが完了するのを待機する trigger.OnStateUpdateAsObservable() .Where(onStateInfo => !onStateInfo.Animator.IsInTransition(onStateInfo.LayerIndex)) // アニメーションの移行が完了するのを待つ .Where(onStateInfo => onStateInfo.StateInfo.normalizedTime > 2.0) // アニメーションの2回目のループ完了を検出する .Take(1) // 一度だけ実行する .Subscribe(_ => { // デフォルトアニメーションに戻る animator.SetBool("ActionFlg", false); }) .AddTo(this); } }
動作確認
シーンを再生して動作を確認します。
LoopAction の2回目のループ完了時に、トリガーで元のアニメーションに戻れば成功です。