MRが楽しい

MRやVRについて学習したことを書き残す

ObservableStateMachineTriggerを使ってUniRxでアニメーションの終了を検知する

本日は UniRx の小ネタ枠です。
ObservableStateMachineTriggerを使ってUniRxでアニメーションの終了を検知する手順を記事にします。
f:id:bluebirdofoz:20210808201747j:plain

前回記事

以下の記事の続きになります。
bluebirdofoz.hatenablog.com

アニメーションの完了をトリガーで待機する

前回の ObservableStateMachineTrigger を応用してアニメーションの完了をトリガーで待機してみます。
トリガーで待機できればアニメーションのループの有無、ループ回数などをスクリプト側で制御できます。

AnimとAnimationControllerの設定

デフォルトではアニメーションをループさせるために、Anim の loop time にチェックを入れます。
f:id:bluebirdofoz:20210808201808j:plain

またアニメーションの終了を命令後、アニメーションが即座に変化するように Transition からは[Has Exit Time]のチェックを外しておきます。
f:id:bluebirdofoz:20210808201840j:plain

サンプルスクリプト

前回作成したスクリプトを以下の通り、改変しました。
シーンの再生と同時に 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);
    }
}

f:id:bluebirdofoz:20210808201854j:plain

動作確認

シーンを再生して動作を確認します。
LoopAction の2回目のループ完了時に、トリガーで元のアニメーションに戻れば成功です。
f:id:bluebirdofoz:20210808201907j:plain
f:id:bluebirdofoz:20210808201917j:plain