MRが楽しい

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

HoloLens2でホロモンアプリを作る その47(async/awaitを使ってモーションを組み合わせた時系列の処理を記述する)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
f:id:bluebirdofoz:20210717225205j:plain

今回は async/await を使ってモーションを組み合わせた時系列の処理を記述するメモです。
以下の記事の実装のリファクタリングになります。
bluebirdofoz.hatenablog.com

1つの関数でモーションを組み合わせた時系列の処理を記述する

async/await を使ってリファクタリングした後の2つの関数例を以下に示します。
・「プレイヤーの方向を向く処理」を単体で行う関数
・「プレイヤーを探す」⇒「プレイヤーの方向を向く処理」⇒「じゃんけん」の3つの処理を時系列に行う関数

/// <summary>
/// 指定ターゲットの方を向くアクションの開始(1モーション例)
/// </summary>
public async UniTask<bool> StartTurnLookTargetAsync(GameObject a_TargetObject)
{
    try
    {
        // アクション名の定義
        HoloMonActionFunction actionFunction = HoloMonActionFunction.TurnLookTarget;

        // ターゲットの方向を向くモードのアクション設定を指定する
        p_HoloMonAction = new HoloMonAction(actionFunction,
            new HoloMonActionSettings(
                new ModeLogicSetting(new ModeLogicTurnTargetData(a_TargetObject)),
                new HeadLogicSetting(new HeadLogicLookAtTargetData(a_TargetObject)),
                new TailLogicSetting(new TailLogicNoOverrideData())
            ));

        // 指定モードのアクションに切り替えて完了を待機する
        ModeLogicResult modeLogicResult =
            await p_HoloMonActUnitChanger.RunActUnitAsync(p_HoloMonAction.ActionSettings);

        return true;
    }
    catch (OperationCanceledException ex)
    {
        Debug.Log(ex.Message);

        return false;
    }
}

/// <summary>
/// じゃんけんで遊ぶアクションの開始(3モーション例)
/// </summary>
public async UniTask<bool> StartJankenTargetAsync()
{
    try
    {
        // アクション名の定義
        HoloMonActionFunction actionFunction = HoloMonActionFunction.JankenTarget;

        // 友人に注目する
        ObjectUnderstandType targetType = ObjectUnderstandType.FriendFace;

        // 指定種別のオブジェクトが見えているか否か
        GameObject targetVisionObject =
            HoloMonFocusOfVisionSingleton.Instance.FindTypeObject(targetType)?.GameObject;

        // モード結果の変数を用意する
        ModeLogicResult modeLogicResult;

        if (targetVisionObject == null)
        {
            // ターゲットが見えていない場合

            // 見回しモードのアクション設定を指定する
            p_HoloMonAction = new HoloMonAction(actionFunction,
                new HoloMonActionSettings(
                    new ModeLogicSetting(new ModeLogicLookAroundData(targetType)),
                    new HeadLogicSetting(new HeadLogicNoOverrideData()),
                    new TailLogicSetting(new TailLogicNoOverrideData())
                ));

            // 指定モードのアクションに切り替えて完了を待機する
            modeLogicResult = await p_HoloMonActUnitChanger.RunActUnitAsync(p_HoloMonAction.ActionSettings);

            // 結果に応じて次のイベントを発生させる
            if (modeLogicResult.FinishModeStatus != HoloMonActionModeStatus.Achievement)
            {
                // ロジックを達成できなかった場合

                // 処理を終了する
                return true;
            }

            // 発見オブジェクトを取得する
            targetVisionObject = modeLogicResult.ModeLogicLookAroundReturn.FindedObject;
        }

        // 振り向きモードのアクション設定を指定する
        p_HoloMonAction = new HoloMonAction(actionFunction,
            new HoloMonActionSettings(
                new ModeLogicSetting(new ModeLogicTurnTargetData(targetVisionObject)),
                new HeadLogicSetting(new HeadLogicLookAtTargetData(targetVisionObject)),
                new TailLogicSetting(new TailLogicNoOverrideData())
            ));

        // 指定モードのアクションに切り替えて完了を待機する
        modeLogicResult =
            await p_HoloMonActUnitChanger.RunActUnitAsync(p_HoloMonAction.ActionSettings);

        // 結果に応じて次のイベントを発生させる
        if (modeLogicResult.FinishModeStatus != HoloMonActionModeStatus.Achievement)
        {
            // ロジックを達成できなかった場合

            // 処理を終了する
            return true;
        }

        // じゃんけんモードのアクション設定を指定する
        p_HoloMonAction = new HoloMonAction(actionFunction,
        new HoloMonActionSettings(
            new ModeLogicSetting(new ModeLogicJankenData()),
            new HeadLogicSetting(new HeadLogicLookAtTargetData(targetVisionObject)),
            new TailLogicSetting(new TailLogicNoOverrideData())
        ));

        // 指定モードのアクションに切り替えて完了を待機する
        modeLogicResult = await p_HoloMonActUnitChanger.RunActUnitAsync(p_HoloMonAction.ActionSettings);

        return true;
    }
    catch (OperationCanceledException ex)
    {
        Debug.Log(ex.Message);

        return false;
    }
}

f:id:bluebirdofoz:20210717225226j:plain

前回の UniRx を利用した記述方法と比べると、処理を入れ子で記述する必要がなく、処理を時系列にかくことができます。
このため分岐を伴う処理はこちらの方が簡潔に記述できます。

動作確認

シーンを再生して動作を確認します。
f:id:bluebirdofoz:20210717225238j:plain

「じゃんけん」の音声を認識すると、ホロモンは最初にプレイヤーを探して周りを見回します。
f:id:bluebirdofoz:20210717225252j:plain

プレイヤーを発見すると見回しのアクションが終わり、ホロモンはこちらを振り返るアクションを開始します。
f:id:bluebirdofoz:20210717225303j:plain

こちらへの振り返り切ると、ジャンケンのアクションが始まります。
f:id:bluebirdofoz:20210717225316j:plain