本日はMRTKを基にHoloLensで使用できるオリジナルのUIを作成します。
過去にSFチックのUIを作成していました。 今回は続編です。
本シリーズで作成したものは以下でMITライセンスで公開しています。(自由に使ってください)
〇機械式UI、非機械式UI
HoloLens 2からはHandTrackingが使用できるようになりユーザーの手を使ったアクションが行えるようになりました。(実機はまだ手元にないですが…)
UIに関してもボタンを押す、つまむ等より自然な動作で入力ができるようになりました。
最近読んでいるこちらの本によるとUIに関して大きく2種類のUIがあり、SF世界のようでありながらユーザーにとって使用しやすいUIは以下の2つを組み合わせることが重要であるとあります。
SF映画で学ぶインタフェースデザイン アイデアと想像力を鍛え上げるための141のレッスン
- 作者:Nathan Shedroff,Christopher Noessel
- 発売日: 2014/07/24
- メディア: 単行本(ソフトカバー)
・機械式UI
レバーやボタン、物理キーボードなどの日常にあふれるUIです。 メリットとしてユーザーは見ただけで操作を理解でき、感覚のフィードバックが必ずあるので誤操作が少ないことが挙げられます。
接触型とも呼べます。 デメリットとして場所を取ることや基本的に一つの機械式UIで一つの動作となることが多いことが挙げられます。
・非機械式UI
スマートフォンタッチパネルやHoloLensのAirTap、音声コマンドや目線など非接触型のUIです。 メリットとして少ないスペースにたくさんの情報を集約することができ、SF映画では必ずと言っていいほど機械式よりも多用されています。
逆にデメリットとして感覚のフィードバックが無い、少ないことにより誤操作やそもそも操作方法の理解ができないことなどのユーザーにとってトラブルとなる現象が発生しやすいことが挙げられます。
非機械式出起こるトラブルの例
この辺りのわかりやすい例としてiPhoneを挙げます。 おじいちゃん おばあちゃんが新しくiPhoneを購入したとします。
iPhoneには説明書は無いのでITに詳しい人ならまだしもですが大抵のおじいちゃん、おばあちゃんはフリップ入力でメールを打つことにストレスと時間がかかってしまいます。
それでも入力することが出来なくてiPhoneを難しいものと捉えてしまうかもしれません。
ところがフューチャーフォン(ガラパゴスケータイ)の場合物理的にボタンがあるので慣れるまで時間はかかったとしてもキー入力が出来ないと言うことは少ないです。
HoloLens 1stでは手をトラッキングするとこはできないためほぼ完全に非機械式UIが使用されていましたが、手がより使用できるようになったことで機械式UIと非機械式UIをミックスさせたような新しいUIが登場しました。
例えばMRTKで提供されているボタンは手の届かない距離からはAirTap、手に届く距離からは指先で押し込むことで擬似的な機械式、非機械式UIをミックスさせています。また、重要なポイントとして触覚フィードバックの代わりに音とアニメーションでフィードバックを返していることで実際にボタンを押しているように錯覚させています。
〇スイッチレバー
これまで本シリーズでは第一弾としてMRTKで提供されているボタンをSFチックにアレンジしたボタン
第二弾としてMRTKで提供されているラジオボタンの機能をアレンジしてディスクリプション(説明)パネル
を作成してきました。
今回第三弾ということでMRTKにあるUIをベースにアレンジするのではなくオリジナルで機械式UIをベースに作成します。
機械式UIでHoloLensのアプリケーション内に現れて何も説明もなしにいきなりユーザーが操作できるUIを考えた結果レバーを作成することにしました。
要件定義は以下のようになります。
①ユーザーが握ってレバーを前後左右に倒せる。
②レバーの倒れ方によって前後左右の入力に相当するイベントが発火する
③レバーを動かすのをやめたらリセットされる。(終了のイベントが発火)
〇ユーザーのアクションの検知
今回大きく3種類のアクションの検知が必要になります。
①ユーザーがレバーを握る
②ユーザーがレバーを動かす
③ユーザーがレバーを離す
①と②は逆の動作でMRTKに提供されている機能を用いることにしました。
ユーザーのアクションを検知するために[Interactable.cs]をゲームオブジェクトにアタッチします。
これでユーザーのアクションを検知できるようになったかというと半分正解、半分不正解で実は[Interactable]コンポーネントのイベントでは[OnClick()]のみが用意されています。
つまり入力のインパクトしか検知できず、入力状態が保持されている情報などは検知できないのです。
MRTKではInteractableコンポーネントを拡張するのとして[InteractableReceiver.cs]が用意されています。
ゲームオブジェクトにInterctableReceiverをアタッチし自身のInteractable.csを設定します。
また、拡張モードの[Event ReceiverType]を握られた状態であることを検知する[InteractableOnPressReceiver]に設定します。
[InteractableOnPressReceiver]は[OnPress()]と[OnRerease()]の二つのイベントを持ち、それぞれpressを検知した瞬間、pressが解放された瞬間に発火します。
〇検知のスクリプト
アクションを検知するための枠組みはできたので次にシンプルなスクリプトを書きます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Switchlever : MonoBehaviour { //Hold Status public bool _ActionEnebled = false; public void leverHoldStat() { Debug.Log("leverActionStart"); _ActionEnebled = true; } public void leverHoldEnd() { Debug.Log("leverActionEnd"); _ActionEnebled = false; } }
ここではBool型の_ActionEnabledがTrue状態の時ユーザーがレバーをつかんでいるときに相当するようにしました。
これをゲームオブジェクトにアタッチ、[InteractableReceiver.cs]の[OnPress()]と[OnRerease()]にそれぞれアタッチし[OnPress()]時に[leverHoldStart()]、[OnRerease()]時に[leverHoldEnd()]が呼び出されるようにしました。
この状態で実行します。
これで①ユーザーがレバーを握る,③ユーザーがレバーを離すの検知ができました。_ActionEnebledがTrueの状態の間処理を行うようにコードを書けば②ユーザーがレバーを動かすも実現できそうです。