14
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

解説!MRTKv2のボタン

Last updated at Posted at 2020-12-13

概要

MRTKは色々な機能が用意されていて本当~に便利なのですが、『「◯◯がしたい!」という目的に対して「MRTKのどの機能がどう使えるのか」が分からない』というのが往々にしてぶつかる壁ではないかなと思います。
本記事ではMRTKで最も使うであろうボタンについて、コンポーネント構成と設定を(分かる範囲で)解説します。
公式ドキュメントと併せて読んで理解を深めていきましょう。

環境

Oculus Quest 2でMRTKを使います。([導入方法はこちら]
(https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/CrossPlatform/OculusQuestMRTK.html))

  • Unity 2019.4.16f1
  • MRTK v2.5.1(Package Manager)

ボタンの作り方

MRTKでボタンを作るには、MRTK Toolboxを使うのが手っ取り早いです。
基本的なUIオブジェクトがまとめられており、ワンクリックでオブジェクトをシーンに配置できます。
image.png
image.png
今回はこちらの「Hololens2 Button 32x32mm」を使います。まずはシーンに配置して、エディタで動作確認しやすいように(0, 0, 0.2)の位置に移動させておきます。
image.png

ボタンを構成するコンポーネントたち

このボタンを構成するコンポーネントは以下の通り。(記事内リンク)

ひとつずつ見ていきましょう。

Transform コンポーネント

言わずと知れた、オブジェクトの位置、回転、スケールを扱うクラスです。
Scene内の全てのオブジェクトは必ずTransformコンポーネントを持ちます。

エディタで動作確認しやすいように(0, 0, 0.2)の位置に移動させておきます。

MRTKには入力シミュレート機能があり、Gameビューを右ドラッグしてポインターを動かし、右クリックでインタラクションできます。(GGVインタラクション
前章でボタンのZ軸の位置を変えたのは、あらかじめGameビューでボタンが見えるように配置することで、このシミュレートをしやすくする意図があります。
GGVPointer.gif

Box Collider コンポーネント

ボタンの当たり判定です。これを非アクティブにするとポインターと指で触れても何も反応しなくなります。ボタンには必須です。
「じゃあボタンを押させたくない時はenabled = falseすればいいんだな」と思いますよね?それはそうなんですけれども、もっといい方法があります。後述
BoxCollider.gif
ちなみにボタンが押されるとBoxColliderも動くのかというとそうではなく、ボタンが押されてもBoxColliderは微動だにしません。

PressableButtonHololens2 コンポーネント

このコンポーネントを展開すると、Gizmoで水色、赤色、黄色、青色の平面が表示されます。これはこのコンポーネントの設定を可視化したものです。
image.png
それぞれが何を意味しているのか見ていきましょう。

Moving button Visuals

GameObject型のSerializeFieldで、ButtonContentというオブジェクトがアタッチされています。
Toolboxから出した状態ではButtonContentオブジェクトはただの空のGameObjectです。
image.png

ボタンを押したときに動いてほしいオブジェクトをここに指定してあげると良さそうです。

Start Push Distance

読んで字のごとく、「ボタンを押したと判断する面」がボタン中心からどれだけ離れているかの距離です。
Gizmoでは水色の面で表現され、これに触れるとTouch Beginイベントが発生します。

Max Push Distance

ボタンを押したときにMovingButtonVisualsのオブジェクトが動く最大距離です。
Gizmoの青い面で表現され、これが負の数値だとTouch Begin Touch Endイベントは発生しても、Button Press Button Releaseイベントが発生しなくなります。正の数値にしておきましょう。

Press Distance

「ボタンが押された」とみなすまでの距離です。Touch Beginイベント後、Button Pressedイベントが発生するまでの押し込み量とも言えるでしょう。Gizmoの黄色い面です。
これを大きめにすることで、いわゆる「軽く触っただけでは反応せず、深く押し込まないといけないボタン」になるでしょう。

Release Distance Delta

Button Pressedイベント後、どのくらいボタンから指を離せばButton Releasedイベントが発生するかの距離です。Gizmoの赤い面で表現されています。

Return Speed

ボタンから指を離したのち、Moving button Visualsのオブジェクトが元の位置に戻る際の速さです。
数値が小さいほど、ゆっくり戻ります。

Release On Touch End

通常、イベントはTouch BeginButton PressedButton ReleasedTouch Endの流れで起こりますが、処理落ちなどによってButton Releaseイベントが発生し損ねるかもしれません。このフラグがセットされていると、その場合にもTouch EndイベントでButton Releaseイベントを発生させるようになります。
つまり、Button Releasedイベントの発生保証と言えるでしょう。

Enforce Front Push

ボタンが前からしか押せないようにします。

Events

このボタンのイベントです。
Button PressedおよびButton Releasedイベントで音を発生させる他、各イベントでPhysicalPressEventRouterコンポーネントのメソッドも呼んでいるようです。(後で詳しく解説します)
この部分は、Unityの標準GUIのボタンと同じように、任意のメソッド呼び出しを登録できるようになっています。
image.png


image.png

Moving Button Icon Text

ボタンを押したときに連動して動く、ボタンのアイコンやテキストのオブジェクトを指定します。
Moving button Visualsで押したときに動いてほしいオブジェクトを指定していましたが、アイコンやテキストはそれとは別で指定できるようになっているようです。
こちらはボタンを押したときにMoving button Visualsオブジェクトの移動量の半分だけ動くようになっています。(アイコンや文字が激しく動きすぎないようにしている?)
image.png

Compressable Button Visuals

ボタンを押したときに潰れるオブジェクトです。同名のGameObjectがあり、輪郭だけ描画するマテリアルをつけたFrontPlateというCubeと、指を近づけたときに光るHighlightPlateというQuadで構成されています。
image.png

Moving button Visualsは単純に移動するだけですが、こちらは押した動きに連動してZ軸に伸縮します。
CompressableButtonVisuals.gif

Min Compress Percentage

ボタンを押しきったときに、Compressable Button Visualsで指定したオブジェクトが元の何パーセントまで潰れるかを設定できます。↑のGIFでZ軸のスケールが0.25~1で変化しているのが見てわかるでしょうか。
ちなみに'Percentage'とありますが、最大値は1です。

Highlight Plate

ボタンにフォーカスしたときにハイライトする部分を指定します。
Compressable Button Visualsに指定したオブジェクトの子にあるHighlightPlateオブジェクトがアタッチされています。
HighlightAnimationTime.gif

Highlight Plate Animation Time

フォーカスしたときにのハイライト表現を、何秒かけて行うかの設定です。


image.png

Button State

これはボタンの状態確認用の表示です。

  • Current Push Distance:ボタンをどのくらい押しているのか
  • Touching:ボタンに触れているか
  • Pressing:ボタンを押しているか

Editor Settings

エディタの設定です。

  • Show Button Event Planes
    Moving button Visualsなどの設定をGizmoで可視化するか
  • Make Planes Editable
    Moving button Visualsなどの設定をドラッグでできるようにするか(有効にすると、Sceneビューで面の端をドラッグして調整できるようになります)
    image.png

PhysicalPressEventRouter コンポーネント

image.png
このボタンにおけるPhysicalPressEventRouterコンポーネントの役割は、PressableButtonHololens2コンポーネントと、後述するInteractableコンポーネントの橋渡しをすることです。

Routing Target

PressableButtonHololens2コンポーネントに連動させるInteractableコンポーネントを指定します。

Interactable On Click

PressableButtonHololens2のどのイベントをInteractableコンポーネントのOn Clickイベント発生のトリガーにするかを選択できます。

  • Event On Click Completion
    PressableButtonHololens2Button Releasedイベント(ボタンを押して、離す)をトリガーにします。
  • Event On Press
    PressableButtonHololens2Button Pressedイベント(ボタンを押す)をトリガーにします。
  • Event On Touch
    PressableButtonHololens2Touch Beginイベント(ボタンに触れる)をトリガーにします。

Interactable コンポーネント

Interactableコンポーネントは、あらゆるオブジェクトをインタラクション可能にする、オールインワンなコンポーネントです。
公式ドキュメントがかなり詳しくまとまっていますので、必読です。
image.png

Inspectorは大きく3つのセクション(General, Profiles, Events)に分かれています。
それぞれ見ていきましょう。


General セクション

States

ボタンがどんな状態を持つかを定義されている、ScriptableObjectです。
このボタンだとFocusPressTouchGrabStatesがアタッチされていますが、その中身は下図の通り。PressedDisabledなど、たくさん種類が定義されています。ここに定義されている7種類の状態を、このボタンが取りうるということが分かります。
image.png

Enabled

このボタンが有効かどうかのフラグです。コード上ではInteractable.IsEnabledでアクセスできます。

「じゃあボタンを押させたくない時はenabled = falseすればいいんだな」と思いますよね?それはそうなんですけれども、もっといい方法があります。

ボタンをただ無効にしたいときはInteractable.IsEnabled = falseを使いましょう。
MonoBehaviour.enabled = falseをしたときはクラス内の全てが無効化されますが、Interactable.IsEnabled = falseを使うと、基本的な見た目の更新を維持しつつ、On Pres入力のみ無効化し、Disabledステート(前述のStatesの一種)に移行させることができます。
これとビジュアルテーマ(後述)を使うと、例えば「無効化したボタンは背景を暗くして、押せないことが一目見てわかるようにする」ような表現が簡単にできるようになります。

Input Actions

このボタンがどんな入力に反応するかの設定でで、このボタンではSelectが設定されています。
このSelectとは、MixedRealityToolkit > Input > Input Actionsで定義されたActionです。
image.png

MixedRealityToolkit > Input > Gesturesで、タップ操作をSelectに紐付けています。要するに、タップすればSelect入力になるようになっています。
image.png

Is Global

Input Actionsでどんな入力に反応するか設定してありますが、Is Globalはその入力がこのオブジェクトに対して行われていなくても入力を受け取るようにする設定です。
このボタンで例えると、Is Globalが有効ならシーン内のどこをエアタップしてもボタンが反応するようになります。(あまり使うことはない設定かも)

Speech Command

Input Actionsではどんな入力に反応するか設定しましたが、こちらはどんな音声入力に反応するかを設定できます。
「Select」と発声することで、このボタンにインタラクションできるということです。

音声入力の設定はMixedRealityToolkit > Input > Speechにあります。
この設定のドキュメントはこちら
image.png

Require Forcus

フォーカスしたときにのみ音声入力を受け付けるかの設定です。これがTrueであるということは、ポインターなどでボタンにフォーカスした上で「Select」と発声することでインタラクション可能だということになります。
Speech Command版、Is Global設定と言えるでしょう。(フラグのつけ方は逆ですが)

Selection Mode

このボタンがどんなボタンなのかの設定です。

  • Button:ただのボタンです。このボタンではこちらが選択されています。
  • Toggle:トグルボタンです。On/Offの二つの状態を持ちます。
  • Multi Dimension:複数の状態を持つボタンです。

Profiles セクション

image.png

Profilesは、インタラクションによって起こるStateの変化に対して、どんなビジュアルの変更をするかを設定できます。

Reset On Destroy

このコンポーネントが削除された時、変更した内容を元に戻すかどうかの設定です。

Target

ビジュアルの変更をするGameObjectを指定します。

Theme

ビジュアルの変更内容について定義したTheme型のScriptableObjectを指定します。

設定済みのビジュアルテーマの解説1:SeeItSayItLabel

このボタンにあらかじめ設定されているProfilesを解説していきます。
まずはHolographicButtonSeeItSayItLabelテーマから。

image.png
ざっくり言うと、ここで設定している動作は以下のような感じです。

  • StateがFocusになったときに、SeeItSayItLabelオブジェクトのScaleを(1, 1, 1)にする動作を開始する(赤枠)
  • Duration秒後(1秒後)にこの動作を完了する(黄枠)
  • ジャストDuration秒に到達するまでScaleは変化させない(黄枠)

実際に、ボタンにフォーカスした1秒後に「SeeItSayItLabel」オブジェクトのScaleが変化しているのが分かるでしょうか。
この動きは、ユーザーに「このボタンは音声でインタラクションできるよ」というのを伝える目的がありそうです。
SeeItSayItLabel.gif

設定済みのビジュアルテーマの解説2:FrontPlate

image.png

もうお分かりですね?このProfileの動作は以下のようなものです。

  • StateがPressedになったとき、FrontPlateオブジェクトをZ軸に0.008m動かす
  • 0.03秒かけて、ゆっくりと変化を適用する

[Compressable Button Visuals](#Compressable Button Visuals)で、押したボタンがZ軸に伸縮するのは説明しましたが、単純にポインターを使ったときはその動きはありません。そのときにボタンの挙動が不自然にならないように、ここでポインターでボタンを押したときの動きを定義しているようです。

FrontPlate.gif

設定済みのビジュアルテーマの解説3:UIButtonSquareIcon

最後にPressableButtonIconテーマです。テーマ名からして、汎用的にボタンに使うことを想定していそうです。
image.png

このテーマは、FocusPhysicalTouchで異なる動きをするようになっています。

  • StateがFocusになったとき、UIButtonSquareIconオブジェクトをZ軸に-0.002m動かす
  • StateがPhysicalTouchになったとき、UIButtonSquareIconオブジェクトをZ軸に-0.0005m動かす
  • 瞬時に変更を適用する(Easingを使用しない)

Events セクション

Unity標準GUIでおなじみのOn Clickイベントにメソッドを登録できます。
image.png

Receivers

Receiversを展開すると、さらに細かくフォーカス時などのイベントにメソッドを登録できます。
登録されているメソッド群を見ると、ボタンにフォーカスしたときにボタン表面にハイライトが入るようにしている他、ボタンを押したときに音を鳴らしています。
image.png

しかし、ボタンを押したときに音を鳴らすのは、PressableButtonHololens2コンポーネントのイベントでもやっていました。これは同じことを二重にやっているのではなく、PressableButtonHololens2の方ではNear Interaction(指で押すなどの近接的な入力)、Interactableの方ではFar Interaction(ポインター&エアタップなどの遠距離からの入力)のPressイベントに対応させているのです。

Interaction Filter

image.png
On Press系のReceiverを扱うときのみ、それがFar InteractionなのかNear Interactionなのかをフィルタリングできます。

しかし、ボタンを押したときに音を鳴らすのは、PressableButtonHololens2コンポーネントのイベントでもやっていました。これは同じことを二重にやっているのではなく、PressableButtonHololens2の方ではNear Interaction(指で押すなどの近接的な入力)、Interactableの方ではFar Interaction(ポインター&エアタップなどの遠距離からの入力)のPressイベントに対応させているのです。

「これをNear And Farすればイベント登録が一回で済むじゃん」というのはそうなのですが、わざわざFar Onlyにして別々にイベント登録しているのは、PressableButtonHololens2の方ではボタンを背面から押せないようにするEnforce Front Pushという設定がありましたが、Interactableにはその区別がなく、背面からでもOnPressイベントが発生してしまうからだと思われます。(より現実的な動きに準ずるためにこのようにしている?)

Audio Source コンポーネント

音の発生源となるコンポーネントです。このボタンでは、ボタンを押したときに音を出すのに使用しています。
AudioSouceコンポーネントを大量に配置するのは負荷的によろしくないので、ある程度数が多くなってきたら、効果音発生用のAudioSourceを用意して統括的に音を出した方がいいかも知れません。

参考:【Unite Tokyo 2018】Audio機能の基礎と実装テクニック

NearInteractionTouchable コンポーネント

Near Interaction(指で押すなどの近接的な入力)をするために必須のコンポーネントです。
実際にこのコンポーネントがついていないと、PressableButtonHololens2コンポーネントに警告が表示されます。
警告に従ってボタンをポチポチ押せばパラメータを設定してくれるので、特に設定で困ることはありません。
image.png
image.png
例えばLocal Forwardはボタンの向きの設定で、PressableButtonHololens2前からのみボタンを押せるようにする設定に使われたりします。

Button Config Helper コンポーネント

最後のコンポーネント、ButtonConfigHelperはMRTK v2.4で追加されました。
名前の通り、ボタン名やイベント登録、アイコン設定などを補助してくれます。
Labels,Basic Events,Iconのセクションに分かれており、Show Component Referencesを有効にすることで、実際に紐付けられているオブジェクトのSerializeFieldが見えるようになります。
image.png

Labels セクション

ボタンのテキストをここでまとめて変更できます。Enable *のチェックを外せば、そのオブジェクトを非アクティブにできます。
image.png

Basic Events セクション

ここにイベントを登録すれば、InteractableコンポーネントのOn Clickイベントに登録されます。登録を解除すれば、Interactableの方でも登録解除されます。便利!
image.png

Icon セクション

ボタンのアイコンを変更できます。
既定のアイコンから選べるほか、任意のフォントを追加して使うことができるようです。
image.png

参考:MRTKでボタンのアイコンセット(IconSet)を作成してアイコンの見た目を変更する


以上でこのボタンの解説は終了です。(長かった...)

参考

14
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?