MRが楽しい

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

HoloLens2でホロモンアプリを作る その85(一定距離以上に離れたプレイヤーを追いかける)

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

今回は一定距離以上に離れたプレイヤーを追いかけるメモです。

ホロモンの視界距離を定義する

以下の通り、ホロモンの視界距離を定義するクラスを作成しました。
ホロモンは成長すると共にスケールが大きく変化するので、それに合わせて視界距離の判定も変化するようにしています。
・VisionRangeArea.cs

using UnityEngine;
using HoloMonApp.CommonSpace;
using HoloMonApp.ConditionSpace;

namespace HoloMonApp.FieldOfVisionSpace
{
    public class VisionRangeArea
    {
        /// <summary>
        /// 距離種別
        /// </summary>
        public enum VisionRangeType
        {
            ZeroArea = 0,
            NearArea = 1,
            MiddleArea = 2,
            FarArea = 3,
        }

        /// <summary>
        /// 視線原点の参照
        /// </summary>
        static public Transform VisionRoot => HoloMonBodySingleton.Instance.Head;

        /// <summary>
        /// ゼロ距離の定義(不変)
        /// </summary>
        static readonly private float ZeroAreaBase = 0.0f;

        /// <summary>
        /// 近距離の定義(不変)
        /// </summary>
        static readonly private float NearAreaBase = 1.0f;

        /// <summary>
        /// 中距離の定義(不変)
        /// </summary>
        static readonly private float MiddleAreaBase = 2.5f;

        /// <summary>
        /// 遠距離の定義(不変)
        /// </summary>
        static readonly private float FarAreaBase = 10.0f;

        /// <summary>
        /// 成長可変距離の定義(ホロモン1m時)
        /// </summary>
        static readonly private float ScaleStretchRange = 2.0f;

        /// <summary>
        /// ゼロ距離(ホロモンサイズ考慮)
        /// </summary>
        static public float ZeroArea =>
            ZeroAreaBase +
            ScaleStretchRange * HoloMonConditionBodySingleton.Instance.
            IReadOnlyReactivePropertyHoloMonBodyStatus.Value.BodyHeight;

        /// <summary>
        /// 近距離(ホロモンサイズ考慮)
        /// </summary>
        static public float NearArea =>
            NearAreaBase +
            ScaleStretchRange * HoloMonConditionBodySingleton.Instance.
            IReadOnlyReactivePropertyHoloMonBodyStatus.Value.BodyHeight;

        /// <summary>
        /// 中距離(ホロモンサイズ考慮)
        /// </summary>
        static public float MiddleArea =>
            MiddleAreaBase +
            ScaleStretchRange * HoloMonConditionBodySingleton.Instance.
            IReadOnlyReactivePropertyHoloMonBodyStatus.Value.BodyHeight;

        /// <summary>
        /// 遠距離(ホロモンサイズ考慮)
        /// </summary>
        static public float FarArea =>
            FarAreaBase +
            ScaleStretchRange * HoloMonConditionBodySingleton.Instance.
            IReadOnlyReactivePropertyHoloMonBodyStatus.Value.BodyHeight;
    }
}

更に以下の通り、視界オブジェクトのラップクラスに距離種別を判定する関数を追加しました。
・VisionObjectWrap.cs

// ...略...
        /// <summary>
        /// 現在のオブジェクト距離の種別ハッシュ値を返す
        /// </summary>
        /// <returns></returns>
        public int CurrentRangeHash()
        {
            if (p_Object == null)
                return 0;

            // 視界原点とオブジェクト間のベクトルを算出し、距離を取得する
            Vector3 betweenVector = p_Object.transform.position - VisionRangeArea.VisionRoot.position;
            float betweenDistance = betweenVector.magnitude;

            // ゼロ距離判定
            if (betweenDistance < VisionRangeArea.ZeroArea) return (int)VisionRangeArea.VisionRangeType.ZeroArea;

            // 近距離判定
            if (betweenDistance < VisionRangeArea.NearArea) return (int)VisionRangeArea.VisionRangeType.NearArea;

            // 中距離判定
            if (betweenDistance < VisionRangeArea.MiddleArea) return (int)VisionRangeArea.VisionRangeType.MiddleArea;

            // 遠距離判定
            if (betweenDistance < VisionRangeArea.FarArea) return (int)VisionRangeArea.VisionRangeType.FarArea;

            return 0;
        }
// ...略...

視界内のプレイヤーオブジェクトの距離種別が変化した際に判定を行い、遠距離に変化していた場合追跡を行う処理を追加しました。
・HoloMonAIFieldOfVisionStudy.cs

// ...略...
        /// <summary>
        /// 遠距離のプレイヤーへ追跡開始の判定を行う
        /// </summary>
        /// <returns></returns>
        private bool RequestTrackingPlayer(VisionObjectWrap a_VisionObjectWrap)
        {
            bool isReactioned = false;

            // 友達が遠距離にいるときは追跡を始める
            if (a_VisionObjectWrap.CurrentRangeHash() == (int)VisionRangeArea.VisionRangeType.FarArea)
            {
                // 友達オブジェクトが遠距離に居る場合はプレイヤー追跡の行動を要求する
                isReactioned = p_HoloMonAI.RequestTrackingPlayer();
                if (isReactioned)
                {
                    // 要求が通った場合は感情のびっくりUIを表示する
                    p_ExternalEnviroment.ExternalEmotionUI.ExclamationStartAsync();
                }
            }
            return isReactioned;
        }
// ...略...

動作確認

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

プレイヤーが近から中距離に見える場合、ホロモンはこちらを見るだけです。
f:id:bluebirdofoz:20211228234159j:plain

そこから遠距離の範囲に離れるとプレイヤーへの追跡を開始しました。
f:id:bluebirdofoz:20211228234213j:plain