MRが楽しい

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

HoloLens2でホロモンアプリを作る その111(再生時にアイテムの管理コンポーネントを追加する)

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

再生時にアイテムの管理コンポーネントを追加する

前回のアイテムの管理方法の見直しに合わせてアイテムの管理に必要なコンポーネントを再生時に追加する形にしました。
例えばホロモンに認識させたいオブジェクトがある場合は、以下の WorldItemAPI コンポーネントのみをルートオブジェクトに設定します。

このコンポーネントはホロモンがアイテムを認識するのに必要な情報を Reset 関数で取得します。
・WorldItemAPI.cs

using HoloMonApp.Content.Character.Data.Knowledge.Objects;
using HoloMonApp.Content.Character.WorldItem.Common;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

namespace HoloMonApp.Content.Character.WorldItem
{
    [RequireComponent(typeof(Collider))]
    [RequireComponent(typeof(Rigidbody))]
    public class WorldItemAPI : MonoBehaviour
    {
        [Header("デフォルト定義")]

        [SerializeField, Tooltip("アイテムの初期設定")]
        private WorldItemDefaultSettings p_WorldItemDefaultSettings;


        [Header("再生時自動生成")]

        [SerializeField, Tooltip("アクセサ参照")]
        private WorldItemAccesserAPI p_WorldItemAccesserAPI;
        public WorldItemAccesserAPI Accesser => p_WorldItemAccesserAPI;


        private void Reset()
        {
            // アイテムの初期設定を作成する
            p_WorldItemDefaultSettings = new WorldItemDefaultSettings(
                new WorldItemDefaultFeatureSettings(gameObject, GetComponents<Collider>().ToList(), GetComponent<Rigidbody>()),
                new WorldItemDefaultLogicalSettings(GetComponents<Collider>().ToList())
                );
        }

        private void Awake()
        {
            // 再生時アイテム操作に必要なコンポーネントを保持する子オブジェクトを作成する
            GameObject logicObject = Instantiate(new GameObject("[Spawn] ItemLogic"), p_WorldItemDefaultSettings.Feature.ItemObject.transform);
            p_WorldItemAccesserAPI = logicObject.AddComponent<WorldItemAccesserAPI>();
            p_WorldItemAccesserAPI.Initialize(p_WorldItemDefaultSettings);
        }
    }
}

アプリが再生されると WorldItemAPI によってアイテム操作に必要なコンポーネントを設定した子オブジェクトが生成されます。

この実装方式の理由

WorldItemAPI コンポーネントのみをルートオブジェクトに設定するのは様々なプロジェクトに簡単にホロモンアプリの仕組みを移植できるようにするためです。
例えば、MRTK のハンドインタラクションのサンプルシーンでも対象オブジェクトに WorldItemAPI を追加するだけでホロモンが対象アイテムを認識できるようになります。
www.youtube.com

ただし再生時にコンポーネントを設定した子オブジェクトを生成するのはコード管理の観点からはあまり適切な手法ではないかもしれません。
基本的には MonoBehavier を利用しない方がコードの流用性やテストのしやすさが向上するためです。
今回の場合、各種スクリプトが MonoBehavier を利用していなければ子オブジェクトを生成する必要もなく、初期化タイミングの問題に悩まされることもなくなります。

ただホロモンアプリにおいては UnityEditor 上の Inspector ビューで各コンポーネントのステータスがリアルタイムに見れることを重視してこの方式を取りました。
ホロモンの行動はそのときホロモンが何を見ているか何を考えているか見てるアイテムがどういう状態かなど様々な要因に左右されるため、各種ステータスをリアルタイムに見れないとホロモンの行動の妥当性が分からないためです。
両方の課題を同時に解決できる方法を模索中です。