MRが楽しい

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

HoloLens2でホロモンアプリを作る その120(アイテムを徐々に引き寄せる)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
今回はホロモンがアイテムを拾う際に対象を徐々に引き寄せる機能を追加しました。

Lerpメソッド

2つの値を補完した値を返します。第三引数に 0 ~ 1 の値を代入して補完の量を設定できます。
0 のとき、開始値と同じになり、1 のとき、終了値と同じになります。0.5 のときは開始と終了の中央値が返ります。

https://docs.unity3d.com/ja/current/ScriptReference/Vector3.Lerp.html

実装コード

以下のようなアイテムのホールド制御を行うコンポーネントを作成しました。
ホロモンがアイテム保持を開始すると 2 秒かけて徐々に両手の間のホールド位置にアイテムを引き寄せます。
時間経過に合わせて補完の量を大きくすることで、アイテムを徐々に引き寄せる動きを実装しています。
・HoloMonItemHolder.cs

(略)
namespace HoloMonApp.Content.Character.Model.ObjectInteractions.HoldItem
{
    public class HoloMonItemHolder : MonoBehaviour
    {
        /// <summary>
        /// ホールド中オブジェクト
        /// </summary>
        [SerializeField, Tooltip("ホールドオブジェクト")]
        private IHoloMonItemHoldAccess p_ItemHoldAccess;

        [SerializeField, Tooltip("ホールド中")]
        private bool p_IsHolding;

        [SerializeField, Tooltip("ホールド経過時間")]
        private float p_HoldTime;

        private float p_HoldThreshold = 2.0f;
        
        /// <summary>
        /// ホールドトランスフォーム
        /// </summary>
        private Transform p_HoldPositionTransform => this.transform;


        // Update is called once per frame
        void Update()
        {
            // ホールド時はトランスフォームを追従する
            if (p_IsHolding)
            {
                if (p_ItemHoldAccess != null)
                {
                    // ホールドの経過時間を加算する
                    p_HoldTime += Time.deltaTime;

                    // 経過時間を基にリープのファクターを調整する
                    // 徐々に手元に引き寄せられる
                    float factor = p_HoldTime / p_HoldThreshold;
                    factor = (factor >= 1.0) ? 1.0f : factor;
                    
                    // Lerpを使って徐々に追従させる
                    Vector3 beforePosition = p_ItemHoldAccess.Position;
                    Quaternion beforeRotation = p_ItemHoldAccess.Rotation;

                    Vector3 afterPosition = p_HoldPositionTransform.position;
                    Quaternion afterRotation = p_HoldPositionTransform.rotation;
                    
                    Vector3 settingPosition = Vector3.Lerp(beforePosition, afterPosition, factor);
                    Quaternion settingRotation = Quaternion.Lerp(beforeRotation, afterRotation, factor);
                    
                    // アイテムを指定トランスフォームにホールドし続ける
                    p_ItemHoldAccess.HoldItem(settingPosition, settingRotation);
                }
            }
        }
(略)