MRが楽しい

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

HoloLens2でホロモンアプリを作る その28(ホロモンが食べ物を引き寄せる)

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

今回はホロモンが食べ物を引き寄せるメモです。

ホロモンが食べ物を引き寄せる

ホロモンが食べ物を口元で食べているように見せるため、食べ物をホロモンの近くに引き寄せる仕組みを実装します。
食べ物などのアイテムオブジェクトに追加するスクリプトに以下の関数を追加しました。
・ItemCommonController.cs

        /// <summary>
        /// 指定の位置にアイテムを保持する
        /// </summary>
        public void FoldItem(Transform a_HoldTransform)
        {
            // フードオブジェクトを保持座標に移動する
            //this.transform.position = a_HoldTransform.position;
            //this.transform.rotation = a_HoldTransform.rotation;

            // 一旦、慣性をリセットする
            this.GetComponent<Rigidbody>().velocity = Vector3.zero;
            this.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;

            // 重力を切る
            this.GetComponent<Rigidbody>().useGravity = false;

            // アタリ判定を無効化する
            this.GetComponent<Collider>().enabled = false;

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

            // 反映前トランスフォーム
            Vector3 beforePosition = this.transform.position;
            Quaternion beforeRotation = this.transform.rotation;

            // 反映後トランスフォーム
            Vector3 afterPosition = a_HoldTransform.position;
            Quaternion afterRotation = a_HoldTransform.rotation;

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

            // 1フレームごとにトランスフォームを徐々に変化させる
            p_LerpTrigger = Observable
                .IntervalFrame(1)
                .Take(lerpTime)
                .SubscribeOnMainThread()
                .Subscribe(
                x =>
                {
                    // Lerpを使って徐々にトランスフォームを変化させる
                    float current = (float)(1.0 / lerpTime) * x;
                    Vector3 settingPosition = Vector3.Lerp(beforePosition, afterPosition, current);
                    Quaternion settingRotation = Quaternion.Lerp(beforeRotation, afterRotation, current);

                    this.transform.position = settingPosition;
                    this.transform.rotation = settingRotation;
                },
                () =>
                {
                    // 完了時は最終的なトランスフォーム値を設定する
                    this.transform.position = afterPosition;
                    this.transform.rotation = afterRotation;
                })
                .AddTo(this);
        }

f:id:bluebirdofoz:20210407232235j:plain

トランスフォームをスムーズに変化させるため、以下の Vector3 と Quaternion の Lerp 関数を利用しています。
docs.unity3d.com
docs.unity3d.com

食べ物を保持する位置はホロモンの子オブジェクトとして位置を決めておきます。
f:id:bluebirdofoz:20210407232311j:plain

食べ物を食べるアニメーションを実行するとき、この子オブジェクトを指定して関数を実行します。
シーンを再生すると、ホロモンの手元に食べ物が引き寄せられてアニメーションが再生されます。
f:id:bluebirdofoz:20210407232321j:plain