View on GitHub

NeosVRJP-Techbook

NeosVRJP-Techbook (NeosVRの応用編・技術ノート)

スロットをアクティブにしてセッションに現れさせる

概要

レニウム(@rhenium_vrc)さんが作ったEZ Cameraはインストールすると、メニューボタンのダブルクリックで、左手にカメラが現れます。これはSet Slot Active Selfを使って、スロットをアクティブにしてカメラをセッションに現れさせています。このLogiXについて解説をしてみましょう。

全体を見渡すと、左の方が入力になっていて、結果は右になっています。左の入力は緑色の矢印が3つあります。緑色はスロットを表しています。上からCamera, Init Point, Ez Cameraとなっています。Cameraは標準のカメラがこのEz Cameraに取り込まれています。Init Pointはインストールしたときの左手との距離、角度、スケールが記録されています。最後にこのLogiXがあるEz Cameraです。それらが分かるようにスロットの中身が表示されています。

右の結果は、大きく3つあります。一番上にSet Slot Active Selfがあり、これを使ってCameraのスロットにActiveを送って、カメラをセッションに表示させることをします。次に真ん中はInit Pointスロットに書かれていることをSet Local PositionSet Local RotationSet Local Scaleを使って設定します。最後に一番下のSet Slot Active Selfはメニューボタンのダブルクリックがあったときに、カメラを表示したり、逆に消したりすることをします。

pic

解説

インストール時にカメラを表示し続ける

一番上のSet Slot Active Selfへの入力を考えると常にTrueが送られるのでActiveにする、つまりCameraをセッションに表示することをします。その条件は2つあって、1つはEz cameraのスロットの親スロットの名前に”pref”があることと、そして2つめがEz cameraのスロットのユーザーが存在していることです。この”pref”というのはプレハブ(prefab)ということで、まだインストールが完了していないときに残っているスロットです。インストールが完了するとEZ Cameraから”pref”というスロットは消えています。

1つめはEz cameraスロットからGet Parent Slotを使って親のスロットを取り出し、さらにGet Slot Nameを使って親の名前を取り出し、これを”pref”が入っているかどうかを検査します。

2つめはGet Active Userを使ってEz cameraスロットを所持しているユーザーをとりだし、Is User Presentでユーザーがいるか検査します。

これらはインストールする際に、カメラを表示し続けるためにあります。

なおUpdateにより毎フレーム処理が実行されているので、この処理が毎フレームごとに行われます。

Init Pointスロットからカメラの位置を初期化する

下の図は最終のインストールが終わったときのEz Cameraスロットの様子をインスペクターで見たところです。Ez cameraスロットの下に、Init Pointがあり、そこにはPosition: Rotation: Scale:についてそれぞれインストールの時の値が保存されています。NeosVRでは、子スロットの位置は親スロットの位置からの相対位置になっています。ですからCameraの位置は親のInit Pointの位置から相対的に決まります。

pic

まず、Set Parentを使って、Init Pointスロットの親をEz Cameraスロットにします。そして、Set Local PositionSet Local RotationSet Local Scaleを使ってCameraスロットの位置、回転角度、スケールを設定します。ここでSet Local PositionとSet Local Rotationの左の入力値がないのですが、これらは(0,0,0)が設定されます。そうするとInit PointスロットがCameraの親なので、Init Pointスロットの位置に設定されます。Init Pointスロットは左手スロットの子供であり、そこからの相対位置を持っています。これによりカメラの位置を初期化します。

pic

メニューボタンのダブルクリックで表示する

Standard Controllerを使ってメニューボタンが押されたかどうかを判定します。そして、Fire On Trueを使ってこのTureの信号をImpulseに変換します。

次に、Sequenceを使って、このImpulseを2つに分けます。しかし同時に2つのImpulseがでるわけではなくて、まず1つめのImpulseはIfをたたきます。そしてIf文は成り立ちません。なぜかというとElapsed Timeでは凄く大きな秒数が出力されているからです。 そしてIf文の判定が終わってから次のImpulseがSequenceから出てきて、 Elapsed Timeにとどき、経過時間が0にセットされて0が出力されます。このときに<はTureを出力します。

ここで続いてダブルクリックをしているので、0.3秒以内に再びメニューボタンが押されると、SequenceにImpulseが流れ、Ifがたたかれます。このときにElapsed Timeでは、前回のインパルスからの経過時間を計っています。これが0.3秒以内であればIf文が成立してImpulseがSet Local Positionに流れます。

このようなやり方でダブルクリックを判定しています。SequenceはImpulseを複数個に分けますが、上から順にImpulseを出していくことに注意が必要です。

Standard Controllerの3つめの入力はGet Slot Active Selfの否定の結果がつながっています。これにより現在CameraがActiveでなければ、Get Slot Active SelfはFalseを返すので、Trueを送り込むことになり、CameraがActiveとなって、セッションに表示されます。逆にCameraが表示されていればGet Slot Active SelfはTrueを返すので、Falseを送り込むことになり、CameraのActiveが外れて、セッションからCameraが表示されなくなります。このようにしてCameraのトグル表示が実現されています。

pic

おわりに

Cameraをセッションに表示させるのには、スロットをActiveにすればいいということが分かります。また初期値の設定の仕方が書かれていました。さらにメニューボタンのダブルクリックによりImpulseを出す方法がありました。

関連しているノード

Host User, Update, Get Active User, Get Parent Slot, Get Slot Name, Containing, Standard Controller, Fire On True, Sequence, Set Slot Active Self, Elapsed Time, Get Slot Active Self, Set Local Position, SEt Local Rotation, Set Local Scale

追記

れにうむ(@rhenium_vrc)さんがよりシンプルなLogiXを提案しています。下記で紹介します。

ダブルクリックを判定する