MRが楽しい

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

HoloLens2でホロモンアプリを作る その117(ヘルプウィンドウが一定時間で消えるようにする)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
今回はヘルプウィンドウが一定時間で消えるようにする修正を行いました。

ヘルプウィンドウが一定時間で消えるようにする

アプリ起動時、ホロモンやアイテムの上部に表示されるヘルプウィンドウの挙動を見直しました。

これまではスタンドの消失に合わせてヘルプウィンドウも消失していましたが、以下のような一定時間が経過するとウィンドウを徐々に縮小して消失するアクションを行うスクリプトを作成しました。
・ItemHelpWindowBehaveController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using System;
using UniRx;

using HoloMonApp.Content.Character.View;
using UnityEngine.Serialization;

namespace HoloMonApp.Content.SupportItem.Objects.Windows.HelpWindow
{
    public class ItemHelpWindowBehaveController : BItemBehaveController
    {
        [SerializeField, Tooltip("ターゲットトランスフォーム")]
        private Transform p_TargetTransform;

        [SerializeField, Tooltip("ターゲットオフセット")]
        private float p_OffsetHeight;
        
        [SerializeField, Tooltip("消失アニメーション中か")]
        private bool p_NowDisappear;

        [SerializeField, Tooltip("消失済みか")]
        private bool p_Disappeared;

        [SerializeField, Tooltip("消失までの秒数")]
        private float p_CheckThresholdSec = 5.0f;

        [SerializeField, Tooltip("現在のカウント")]
        private float p_CheckCountSec = 0.0f;

        [SerializeField, Tooltip("デフォルトスケール")]
        private Vector3 p_DefaultScale = Vector3.one;

        /// <summary>
        /// 消失トリガー
        /// </summary>
        private IDisposable p_DisappearLerpTrigger;

        public void SetTrackingTransform(Transform a_TrackingTarget)
        {
            // 追跡対象を設定する
            p_TargetTransform = a_TrackingTarget;
            p_OffsetHeight = 0.0f;
        }
        
        public void Initialize()
        {
            // 消失アニメーション中は処理しない
            if (p_NowDisappear) return;
            
            // 追跡対象をリセットする
            p_TargetTransform = null;
            p_OffsetHeight = 0.0f;
            
            // チェック変数をリセット
            p_Disappeared = false;
            p_CheckCountSec = 0;
            
            // オブジェクトを表示する
            this.transform.localScale = Vector3.one;
        }
        
        private void LateUpdate()
        {
            // 消失済みなら処理しない
            if(p_Disappeared) return;
            
            p_CheckCountSec += Time.deltaTime;
            
            // 一定時間経過したら焼失させる
            if (p_CheckCountSec > p_CheckThresholdSec)
            {
                DisappearObject();
            }

            // 追跡動作
            TrackingMove();
        }

        /// <summary>
        /// 追跡動作
        /// </summary>
        void TrackingMove()
        {
            if (p_TargetTransform == null) return;

            // ターゲットトランスフォームのオフセット分の高さに置く
            this.transform.position = new Vector3(
                p_TargetTransform.position.x,
                p_TargetTransform.position.y + p_OffsetHeight,
                p_TargetTransform.position.z);

            // ターゲットトランスフォームの方向を向く
            this.transform.rotation = p_TargetTransform.rotation;
        }

        /// <summary>
        /// オブジェクトを消失させる
        /// </summary>
        private void DisappearObject()
        {
            // 消失アニメーション中は処理しない
            if (p_NowDisappear) return;

            p_NowDisappear = true;

            // スムーズにトランスフォームを移動させる
            // 分割フレーム数
            int lerpTime = 10;

            // 反映前トランスフォーム
            Vector3 beforeScale = p_DefaultScale;

            // 反映後トランスフォーム
            Vector3 afterScale = Vector3.zero;

            // トリガーを設定済みの場合は一旦破棄する
            p_DisappearLerpTrigger?.Dispose();

            // 50ミリ秒ごとにトランスフォームを徐々に変化させる
            p_DisappearLerpTrigger = Observable
                .Interval(TimeSpan.FromMilliseconds(50))
                .Take(lerpTime)
                .SubscribeOnMainThread()
                .Subscribe(
                    x =>
                    {
                        // Lerpを使って徐々にトランスフォームを変化させる
                        float current = (float)(1.0 / lerpTime) * x;
                        Vector3 settingScale = Vector3.Lerp(beforeScale, afterScale, current);

                        this.transform.localScale = settingScale;
                    },
                    () =>
                    {
                        // オブジェクトを完全に消失する
                        this.transform.localScale = Vector3.zero;
                        
                        // 消失アニメーション完了
                        p_NowDisappear = false;
                        p_Disappeared = true;
                    
                        // オブジェクトを無効化する
                        this.gameObject.SetActive(false);
                    })
                .AddTo(this);
        }
    }
}

スクリプトをヘルプウィンドウのオブジェクトに設定しておくことで、アプリ起動後、一定時間経過するとヘルプウィンドウが自動で消失するようになりました。