MRが楽しい

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

HoloLens2でホロモンアプリを作る その121(アイテムの消失処理を共通化する)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
今回はアイテムの消失処理を共通化しました。

アイテムの消失処理

スタンドやウィンドウ、ホロモンが食べ物を食事した場合などでアイテムを徐々に小さくして消失させる処理を利用しています。
今回はこれらのアイテムに共通の基底クラスを作成し、そこに消失処理のメソッドを実装することで処理を共通化しました。

アイテムの基底クラスとして以下のクラスを作成しました。
・BItemAccessAPI.cs

using System;
using HoloMonApp.Content.Character.Data.Knowledge.Objects;
using UniRx;
using UnityEngine;

namespace HoloMonApp.Content.SupportItem.Objects
{
    public abstract class BItemAccessAPI : MonoBehaviour
    {
        // (略)
        
        private bool disappearFlg = false;
        private IDisposable isappearLerpTrigger;
        
        /// <summary>
        /// アイテムを徐々に消失させる
        /// </summary>
        public void DisappearObject()
        {
            // 消失中の場合は処理しない
            if (disappearFlg) return;
            disappearFlg = true;
            
            // 消失アニメーション時間を設定する
            float learpTime = 0.5f;
            
            // スムーズにトランスフォームを移動させるためフレームの分割数を設定する
            int lerpTime = (int)(learpTime / 0.025f);

            // 反映前トランスフォーム
            Vector3 beforeScale = this.gameObject.transform.localScale;

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

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

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

                        this.gameObject.transform.localScale = settingScale;
                    },
                    () =>
                    {
                        // 完了時はオブジェクトを非表示にしてトランスフォームを戻す
                        this.gameObject.transform.localScale = beforeScale;

                        // オブジェクトを非表示にする
                        this.gameObject.SetActive(false);
                        disappearFlg = false;
                    })
                .AddTo(this);
        }
    }
}

この基底クラスをスタンドや育成アイテムのクラスで継承して利用しています。
以下は浮遊スタンドアイテムのクラス例です。
スタンド上のオブジェクトがなくなった通知を受け取ると基底クラスの消失処理を呼び出します。
・ItemStandAccessAPI.cs

namespace HoloMonApp.Content.SupportItem.Objects.Stands
{
    public abstract class ItemStandAccessAPI : BItemAccessAPI
    {
        // (略)
    }
}

・ItemFloatingStandAccessAPI.cs

namespace HoloMonApp.Content.SupportItem.Objects.Stands.FloatingStand
{
    public class ItemFloatingStandAccessAPI : ItemStandAccessAPI
    {
        [SerializeField]
        private ItemFloatingStandBehaveController itemFloatingStandBehaveController;

        private void Start()
        {
            itemFloatingStandBehaveController.OnDisappearObservable
                .Subscribe(_ => base.DisappearObject())
                .AddTo(this);
        }
        // (略)
    }
}

これでオブジェクト消失の処理をどのアイテムでも簡単に呼び出せるようになりました。