Hiromuブログ

最近はこちら(https://zenn.dev/hiromu)が本体

MRTK:Hierarchyからの確認

概要を確認した次はエントリポイントからの確認として Unity の Hierarchy から実装を見ていきます。

確認環境

  • Unity 2019.3.7f1
  • MRTK v2.4.0

Hierarchy の確認

まず、MRTKをインポートし、メニューの [Mixed Reality Toolkit] > [Add to Scene and Configure...]を選択します。 この時点ですでに最低限動作をする状態となっているため、Hierarchy を確認します。

f:id:HiromuKato:20200624184843p:plain

この中で、MixedRealityToolkit の子にある複数の GameObject は UnityEditor 上でアクティブなサービスを可視化するために表示しているだけのもの(*1)なので、無視すると具体的に見る必要があるコンポーネントは以下の4つになります。

  • MixedRealityToolkit オブジェクト

    • MixedRealityToolkit コンポーネント
      f:id:HiromuKato:20200624184951p:plain
  • Main Camera オブジェクト

    • EventSystem コンポーネント
    • MixedRealityInputModule コンポーネント
    • GazeProvider コンポーネント
      f:id:HiromuKato:20200624185014p:plain

この4つのスクリプトを元にして MRTK は動作していることになります。 この中で、EventSystem は Unity の機能であり MRTK の実装ではありません。

また、MixedRealityInputModule は StandaloneInputModule を継承したもので EventSystem と一緒に用いて動作するものになるため uGUI を利用する際に必要なものとなります。

確認として MixedRealityInputModule コンポーネントを削除して PressableButtonHoloLens2 プレハブのボタンを配置してみても問題なく操作できます。(なお EventSystem は削除するとエラーがでます)

従って、uGUI はひとまず利用しない前提で考えると、MRTK の中身を把握していくためには、以下2つのコンポーネントを掘り下げていけば良いことになります。(たったの2つ!)

  • MixedRealityToolkit コンポーネント
  • GazeProvider コンポーネント

MixedRealityToolkit コンポーネント

概要

  • Mixed Reality Toolkit の操作の調整を担当する
  • プロジェクト全体で唯一のシングルトン(サービスロケーターパターンになっている)
  • プロジェクト内で使用されるすべてのアクティブなサービスのサービスレジストリを提供する(サービスの登録・解除・取得を行う)とともに、プロジェクトのアクティブな構成プロファイルを提供する(プロファイルで設定した内容にどこからでもアクセスできる)
  • プロファイルは、プロジェクトのニーズを満たすためにいつでも交換できる(ランタイムでの交換は現状未対応:ここの Note の欄に記載されている)

継承関係

f:id:HiromuKato:20200624185036p:plain

次に、MonoBehaviour を継承したものなので イベント関数の実行順序 の順に追っていきます(終了関連の処理は省略)

実行順の動作確認

  • Awake()

    • MixedRealityToolkitインスタンスを登録する(インスタンスを toolkitInstances リストへ追加する、マルチシーンの場合はMixedRealityToolkitインスタンスが複数になることがあるため)
    • インスタンスの初期化処理を行う
    • サービスロケーターの初期化(プロファイルに設定されているサービスをソートして登録)
    • 登録したサービスをそれぞれ順番に初期化する(具体的な処理は対応するサービスに委譲)
  • OnEnable()

    • プロファイルに設定されているサービスを順番に有効にする(具体的な処理は対応するサービスに委譲)
  • Start() なし

  • Update() / LateUpdate()

    • プロファイルに設定されているサービスを順番に更新する(具体的な処理は対応するサービスに委譲)

GazeProvider コンポーネント

概要

  • ゲイズの機能 (ヘッドと視線の両方) は、GazeProvider によって提供される
  • 他の入力ソースと同様に、GazeProvider はポインターを使用してシーン内のオブジェクトとインタラクションする
  • GazeProvider の場合、ポインターは InternalGazePointer によって実装され、プロファイルによって設定されていない

継承関係

f:id:HiromuKato:20200624185054p:plain

実行順の動作確認

  • MixedRealityInputSystem 初期化の段階で、GazePointar へのアクセスがあるので、OnEnableよりも前に InitializeGazePointer メソッドが呼ばれ、ポインターの生成・初期化を行っている。またカーソルも生成される(InitializeGazePointerの中にブレークポイントを張って実行すると確認できる)。

  • Awake() なし

  • OnEnable()

    • 親クラス(InputSystemGlobalHandlerListener) の OnEnable から RegisterHandlersメソッドが呼ばれ、GazeProviderのオーバーライドしたRegisterHandlersメソッドが呼ばれる
    • RegisterHandlersメソッド で GazeProvider 自身を IMixedRealityInputHandler としてグローバルリスナーに登録する
      • Input Up/Down をグローバルに受け取ることができるようになる
  • Start()

    • OnEnable で InputSystem が取得できなかった場合は、改めて取得し RegisterHandlers メソッドを呼ぶ
    • カーソルを表示する
    • RaiseSourceDetected メソッドを呼び、ゲイズの入力ソースが検出されたときの処理を行う
  • Update()

    • デバッグ用のレイ表示など
  • LateUpdate()

    • 頭の速度(HeadVelocity)を更新
    • 頭の移動方向(HeadMovementDirection)を更新

シーンの実行

次にシーンを実行してみたときの Hierarchy です。

f:id:HiromuKato:20200624185113p:plain

以下のゲームオブジェクトが追加されています。

  • Diagnostics(プロファイルでオンにしている場合)
  • DefaultCursor(Clone)
  • None_GGVPointer
  • UIRaycastCamera

これらの GameObject は MixedRealityToolkit または GazeProvider (またはその中で新たに生成されたオブジェクトの中)で生成されていると言えます(*2)。

まとめ

MixedRealityToolkit コンポーネントがサービス全体のとりまとめをおこなっていることがわかりました。プロファイルで利用したいサービスの具象クラスを設定するようになっているので、さらに詳細を把握したい場合は、その具象クラスを追っていけば良いことがわかります。

f:id:HiromuKato:20200624185132p:plain


(*1) プロファイルの Editor > Use Service Inspectors のコメントを見るとそう書かれており、チェックを外すと Hierarchy から GameObject も削除されます
f:id:HiromuKato:20200624211147p:plain

(*2) 実際に生成されている場所は以下

  • DefaultCursor(Clone) :

    • GazeProvider クラスの InitializeGazePointer メソッド
  • None_GGVPointer :

    • BaseInputDeviceManager クラスの CreatePointer メソッド(具象クラスはUnityEditorで実行している場合はInputSimulationService)
    • GGVPointer クラスの中で GameObject 名が "GGVPointer(Clone)" から "None_GGVPointer" に書き換えられている
  • UIRaycastCamera :

    • FocusProvider クラスの FindOrCreateUiRaycastCamera メソッド