はじめに
コントローラーを使用したテキスト入力の記事は調べたところいくつかヒットしたが、ハンドトラッキング(手)のみの操作で入力できるようにしたという記事を見かけなかったので作成しました
デモ
パススルー状態での撮影なので、背景が真っ暗です
大まかな実装の方法
- ハンドトラッキングの有効化
- Poke(押し込み)の実装
- スクリプトでのOSのキーボードを呼び出し
- Poke(押し込み)の判定を外部で利用可能にする
- キーボードの入力内容とInputを同期
環境
バージョン
Unity 2022.3.11.f1
導入したSDK(v62)
SDKは以下のURLから無料でダウンロードできる
https://assetstore.unity.com/publishers/25353
- Meta XR Core SDK
- Meta Interaction SDk
- Meta Interaction SDK OVR Intergration
いずれも v62 でダウンロードしている
実装方法
冒頭であげた5つに分けて解説していく
プロジェクトへのSDKのインポートなどは終わっているものとする
1. ハンドトラッキングの有効化
Oculus > Building Blocksを選択し、以下のものを追加する
- CameraRig
- Hand Tracking
- Virtual Hands
PassThrough は有効にしなくても問題ないが、以下の通りになる
パススルーを有効にした場合は Build の設定や Android の設定を変更する必要があるため注意
2. Poke (押し込み)の実装
Poke については非常に分かりやすい解説をされている方がいたのでそちらのリンクを貼っておく
ダイレクトタッチ(ポーク)を実現する Poke Interaction の概説【Oculus Interaction SDK】
今回は Building Blocks を流用して実装する
BB のウィンドウから Poke を選択し、シーンに追加する
Surface が実態に指先で触れられる範囲を示し、Visuals 中に表示するボタンが入っている
今回は Surface のサイズを テキストの入力エリアを覆うように設定し、Visuals は Mesh を解除し表示しないようにした
これで テキスト入力エリア に触れたかどうかの判定が可能になる
3. スクリプトでのOSのキーボードを呼び出し
概要としては InputField を読み込んで、キーボードでの変更内容を順次保存していく方法である
以下にサンプルコードを示す
using TMPro;
using UnityEngine;
public class UseKeyboard : MonoBehaviour
{
// InputField の読み込み
[SerializeField] private TMP_InputField inputField;
// 保存先
private string Output;
public bool isOpen = false;
// キーボードの宣言
private TouchScreenKeyboard _overlayKeyboard;
// キーボードの変更時のみ動く
private void Update()
{
if (_overlayKeyboard.text == "") return;
if (isOpen)
{
inputPassField.text = _overlayKeyboard.text;
Output = inputField.text;
}
}
// キーボードを呼び出す関数
public void SetKeyboard()
{
_overlayKeyboard = TouchScreenKeyboard.Open(Output, TouchScreenKeyboardType.URL);
isOpen = true;
}
}
4. Poke(押し込み)の判定を外部で利用可能にする
先ほど実装した Poke の一番外側の要素に InteractableUnityEventWrapper
を Add Component する
Interactable View に追加した要素をドラッグする
以下の写真の通りになる
それぞれの要素については割愛するが、今回は When Select() を使う
When Select () で + を選択し、さきほど書いたコードを追加した要素をドラッグ
UseKeyboard > SetKeyboard
を選択する
5. キーボードの入力内容とInputを同期
1 つしか テキストを入力エリア がない場合は先ほどの実装で問題ないが、2 つ以上の要素がある場合は Update が実行されたときに両方の処理が走らないように処理を分岐させる必要がある
またキーボードを呼び出したとき以下の関数の実装を行ったが、
// キーボードを呼び出す関数
public void SetPassKeyboard()
{
_overlayKeyboard = TouchScreenKeyboard.Open(Output, TouchScreenKeyboardType.URL);
isOpen = true;
}
TouchScreenKeyboard.Open()
の第一引数(今回では Output
)が正しく指定されていない場合、予期せぬ挙動を起こす場合があるので注意
おわりに
以上でおそらくハンドトラッキングのみでのテキストの入力が可能になると思います
Unity も MetaQuest も c# もほとんどからっきしの状態から検証を含めた実装までに3日を要したので大変でしたが、書き出してみるとあっさりとしたものですね
既存の記事はコントローラーを使用するものが多く、入力の判定がハンドトラッキングほど面倒ではないようで便利そうだなと感じました
今回のアプリの要件としてハンドトラッキングでの入力しか対応させないのであまり関係のない話なのですけどね...
同じところでつまづく人がいませんように
参考文献
Unity + Meta Quest開発メモ
Meta XR SDK(V62)でQuestアプリを開発
Unity Meta SDK ダウンロードリンク(v60以降)
Building Blocks による Meta Quest 3 アプリの作成
ダイレクトタッチ(ポーク)を実現する Poke Interaction の概説【Oculus Interaction SDK】
Meta Questでシステムのバーチャルキーボードを呼び出す方法
キーボードオーバーレイを有効にする