エイバースの中の人

アプリとWEBサービスを作っているABARSのBLOGです。

VR

Unity+WindowsMRでメニューキーの入力を取得する

UnityでWindowsMRの開発を行う場合、通常はUWPでの開発が必要ですが、SteamVRをインストールしていると通常のStandaloneモードで開発することができます。その際、ProjectSettingsのXR SettingのVirtualRealitySupportのチェックボックスを入れるだけで、Main Cameraが自動的にステレオカメラになり、位置と方向が反映されます。

virtual_reality


コントローラの入力を取得する場合、スティックはInputManager、ボタンはInput.GetKeyを使用します。スティックの入力を取得するには、InputManagerで名前を登録した後、Input.GetAxis ("Horizontal2")のようにします。トリガーの入力を取得するには、Input.GetKey(KeyCode.JoystickButton14) のようにします。

input_manager


ここまで、開発は順調に進んでいたかのように見えたのですが、WindowsMRでメニューキーの入力を取得しようとしてトラブルが起きました。以下のサイトのキーコードに従って、Input.GetKey(KeyCode.JoystickButton6)としても、反応しないのです。

Input for Windows Mixed Reality

調査を進めたところ、WindowsMRでもStreamVRを使用している場合は、OpenVRのキーコードに従う必要があることがわかりました。具体的に、Input.GetKey(KeyCode.JoystickButton0)とするとキー入力が取得できました。

Input for OpenVR controllers

ヘッドマウントディスプレイは、Acer、Samsung Odyssey、Dell Visorの三種類を試しましたが、眼鏡に一番やさしいのはDell Visorでした。Oculus Goよりも余裕があり、セルフレームでも締め付けられません。



Dell Visorの箱はとても大きいので、以下のケースがおすすめです。

Gear VR 2016年版と2017年版の比較

Gear VR 2016年版(SM-R323)と2017年版(SM-R324)を比較してみました。

IMG_2323


こちらが2016年版です。アタッチメントが黒です。Galaxy S8は指で押すと、若干ですが、上下に動きます。

IMG_2322


こちらが2017年版です。アタッチメントが灰色です。Galaxy S8は、かっちりと固定され、指で押しても上下に動きません。

IMG_2321


当初は、USB-Cアタッチメントの差だけかと思っていたのですが、2017年版のUSB-Cアタッチメントを2016年版に装着してみても、上下のゆらぎは改善しませんでした。どうやら、スマートフォンを上下から挟み込む3連の出っ張りの高さも違うようです。

結論として、2016年版と2017年版は、筐体もアタッチメントも差分があるため、2017年版を購入した方がよいようです。

Galaxy S8でGear VRの熱問題は解決したか

Gear VRの最大の問題は熱です。Galaxy S6で動画を見ていると、15分程度で熱の警告が表示され、フレームレートが大きく低下します。

この問題は、Galaxy S6をファンで冷却することで改善することができます。具体的には、扇風機の前でプレイするか、サンワダイレクトのスマートフォンクーラーで冷却することで、改善します。

IMG_2300


しかし、サンワダイレクトのスマートフォンクーラーは、ホールド力が弱く、うまくGear VRに固定できず、ストラップを通して無理やり固定したため、視力調整が難しくなってしまいました。また、クーラー自体もMicro USBで充電しないといけないのが不便です。その結果、ほとんど使わず、扇風機で対処していました。

Galaxy S8では、SOCのプロセスの進化の恩恵で、劇的に熱問題が改善しています。以下の記事では、GearVRをサーマルカメラで計測したところ、同条件で、Galaxy S7が50度、Galaxy S8が39度まで改善することが示されています。

Galaxy S8 vs. Galaxy S7: Which is best for VR?

実際、Galaxy S8を使い始めた以降、動画・ゲーム・インターネットのいずれでも、一度も熱警告は発生していません。

Galaxy S6では負荷の低いアプリでも熱警告が頻発するため、Gear VRを使用する場合、Galaxy S6ではなく、Galaxy S8を選択するのがよさそうです。

Gear VRの2016年版をGalaxy S8で使えるか

Gear VRには2016年版と2017年版があります。2016年版の型番はSM-R323、2017年版の型番はSM-R324です。2017年版にはコントローラが付属します。2016年版のGear VRはGalaxy S8でも使用できるのでしょうか。

そもそも、Galaxy S8はUSB-Cです。Gear VRは、USB端子がアタッチメント方式になっており、Micro USBとUSB-Cを切り替えられるようになっているため、USB-Cアタッチメントがあれば接続できそうです。

2016年版には、USB-Cアタッチメントが付属するものと、付属しないものがあります。もともと、USB-CはGalaxy Note 7用のものであり、Galaxy Note 7のバッテリー問題以後、USB-Cのアタッチメントは同梱されなくなりました。そのため、Amazonやメルカリには、Gear VRの2016年版が安価に出品されていますが、USB-Cのアタッチメントが付属するかどうかは、事前に確認が必要です。

USB-Cのアタッチメントがあれば、接続できそうです。ということで、実際に接続してみました。

IMG_2314


接続したところ、Galaxy S8はGear VRを認識し、問題なく動作しました。視野的にも問題は感じず、Galaxy S6と同等の見栄えです。ただ、Gear VR本体とGalaxy S8のホルダーに若干、遊びがあるためか、Gear VRを強く降ると、若干、がたつきがあるように感じます。

海外のフォーラムで調査してみると、2016年版と2017年版では、数ミリcm程度、アタッチメントのサイズが異なるという情報がありました。

比較画像

若干のがたつきは、この数ミリが影響しているのかもしれません。

公式には、Galaxy S8で使用できるのはSM-R324だけとなっているため、基本的には2017年版の新型を使った方が良さそうです。

UnityでGoogle Cardboardのマグネットボタンに対応する

UnityでGoogle Cardboardに対応したアプリを開発する場合、描画部分はDurovis DiveのSDKを使えばよいのですが、Durovis Diveにはマグネットボタンが存在しないため、マグネットボタンへの対応は自分で行う必要があります。

マグネットボタンの判定には、Input.compass.rawvectorを使います。rawvectorにどのような値が入るかは、Androidアプリの内蔵センサーで計測することができます。

CardboardにNexus5を入れた状態で、マグネットボタンを押していない場合、左側面が受ける磁気強度は100マイクロテスラ程度ですが、マグネットボタンを押すと、500マイクロテスラ程度の大きな値になります。従って、以下のように、磁気強度が大きくなった点を検出すれば、ボタンが押されたかを検出することができます。

Vector3 now=Input.compass.rawVector;
int thre=250;
if(Mathf.Abs(prev.x)<thre && Mathf.Abs(now.x)>=thre){
Debug.Log("Hit");
}
prev=now;


磁気強度は磁石によると思うので、しきい値には、ある程度のマージンを設定しておく必要があります。

スマートフォンVRの光学系の設計

3DプリンタでGoogle Cardboardを作る上で、レンズの焦点距離と、レンズとスマートフォンの距離をどう設計すればよいかを考える必要があります。

スマートフォンVRでは、凸レンズで生成される虚像を用いて拡大を行います。そのため、スマートフォンは、焦点距離の内側に設置する必要があります。

そこで、レンズの焦点距離を44mm、レンズとスマートフォンの距離を40mmで設計したところ、文字がぼやけて表示されてしまいました。次に、焦点距離が60mmのレンズを使ってみたところ、かなりいい感じに表示されました。これで完璧かと思ったのですが、別の人に試してもらった所、逆に、焦点距離が44mmのレンズの方がよく見え、焦点距離が60mmのレンズだと像が2つに見えてしまうとコメントをもらいました。

IMG_1158

どうやら、レンズの最適な焦点距離は、見る人の視力に依存していることが分かってきて、その理由を調べました。その結果、これは、虚像の結像位置の問題ではないかという結論に達しました。具体的に、レンズとスマートフォンの距離をs、レンズの焦点距離をfと置くと、虚像は(fs)/(f-s)の位置に出来ます。つまり、(fs)/(f-s)の位置にある物体を裸眼で見ているのと同じ状態になります。

kyori

実際に、手元にある3つのレンズについて、焦点距離と虚像の結像位置を計算してみます。レンズとスマートフォンの距離sは40mmとします。

レンズ価格焦点距離結像位置
望遠鏡組立キットBK用凸レンズ1枚272円44mm44cm
ダイソーミニルーペ2枚100円60mm12cm
Amazon アーテック 凸レンズ1枚70円70mm9.33cm


焦点距離44mmのレンズでは44cmの位置に結像し、焦点距離60mmのレンズでは12cmの位置に結像します。正常な視力の人は、25cmより遠い位置にある物体しか見ることができないため、焦点距離60mmのレンズでは結像位置が近すぎて、像が2つになります。逆に、強い近視の人は、焦点距離44mmのレンズでは結像位置がやや遠く、文字がぼやけて見えます。

従って、Google Cardboardを作る場合、視力が悪い人はダイソーのレンズで十分ですが、視力がよい人は焦点距離45mm程度のレンズを調達する必要がありそうです。もしくは、焦点距離fを60mmに固定すると、s=5.28cmで、焦点距離44mmのレンズと同じく44cmの位置に結像するので、1.28cm程度、スマートフォンとレンズの距離を離してやるとよさそうです。

UnityでGoogle Cardboard用のコンテンツを作成する

Google CardboardのAPIはUnityに対応していません。しかし、Durovis DiveがGoogle Cardboardと同じ原理で動作するため、Durovis DiveのSDKを使うと、簡単にGoogle Cardboard用のアプリを開発することができます。

まず、Durovis Diveの”Download the Plugin Package: Dive Unity Plugin Package 1.6 for Android/ iOS.”からプラグインをダウンロードします。Oculusと違って、PCではネイティブプラグインを使用していないため、無料版のUnityだけでコンテンツを開発することができます。

Dive Unity Pluginにはジャイロセンサーに対応したカメラが含まれているため、既存のカメラを置き換えるだけでVR対応が可能です。

dive_camera

試しに、Unity Chanのアセットにカメラ(Assets/Dive/Dive_Camera)を置いてみました。これをAndroid向けにビルドするだけでUnity Chanを眺めることができます。Build SettingのDefault OrientationはLandscape Leftに設定して下さい。

IMG_1136

デフォルトだと、ソフトキーが表示されて中央寄せにならないので、ソフトキーを非表示にするために、HOW TO ENABLE “IMMERSIVE MODE” FOR ANDROID APPS IN UNITYの一番下にある、DOWNLOAD UNITY PACKAGE FOR EASY IMPORT INTO PROJECTからUnity Packageをインストールするとよいようです。

MMD向けのコンテンツをVRで手軽に楽しめる日は近いと思います。

---
2015/6/30追記

Google Cardboard SDKに、公式のUnity Pluginが追加されたので、今からVRコンテンツを作成するならCardboard SDKがおすすめです。Dive SDKはlibc++に対応していないため、Unity5のiOSビルドでリンクエラーが発生します。Cardboard SDKの場合、libc++に対応しているので、Unity5でも使用できます。テクスチャが点滅する場合は、Development Buildのチェックを有効にする必要があるようです。

Google Cardboardを3Dプリンタで作ってみた

ダンボールに続き、今度は3DプリンタでGoogle Cardboardを作ってみました。使用した3Dプリンタは、3D SystemsのCubeです。低価格のダヴィンチとも迷ったのですが、いかんせん大きすぎるのでCubeにしました。結果的には、PLA樹脂が必要だったので、Cubeでよかったと思います。

まず、デザインファイルにあるlaser_cut.epsを、Autodeskの無料の3D CADツール 123D Designで読めるようにするために、svgに変換します。変換にはCloud Convertを使いました。

変換した後、123Dに読み込ませます。Import SVG -> As Solidを選ぶと、自動的にメッシュまで貼ってくれます。ただ、この段階だと高さがないので、Transform -> Scale -> Non Uniformで高さを付けます。また、デフォルトだとスケールがとても大きくなってしまっているので、Cubeの印刷可能サイズの14mm未満となるよう、0.285倍しました。

123d

後は、Cubeで印刷できるように、パーツ分割し、Export STLでパーツごとにSTLファイルに書き出します。書きだしたSTLをCube Softwareに読み込ませ、BuildしてCubeファイルを書き出せば、準備は完了です。

cube

最初はABS樹脂で作成していたのですが、パーツが薄いのと、印刷面積が大きいこともあって、反りがひどく、まともに印刷できませんでした。

IMG_1125

なので、途中でPLA樹脂に変えました。PLA樹脂にすると、1.4mm幅の高さ方向の積層も問題なくできました。

IMG_1132

合計、20時間ぐらいかけて、完成した初号機がこちらです。

IMG_1133

白のABS樹脂が結果的に使えなかった関係で、付属のPLA樹脂の鮮やかな緑になりました。何はともあれ、アニメイトで調達したミクさんのシールを貼ってみました。

IMG_1134

レンズは100円ショップのルーペを分解したものです。レンズを挟むパーツは、ダンボールに比べて弾性がない関係で、3枚ではなく2枚でぎりぎりでした。100円ショップのレンズが直径3cmなので、それに合わせて3.1cm程度まで穴を拡張すれば、3枚いけるかもしれません。そもそも、レンズに合わせたくぼみを作って、土台のパーツと一体化した方がよいと思います。

マグネットボタンは、ダンボールより格段に操作しやすくなりました。剛性のあるプラスチックの強みです。

初めての3D CADと3Dプリンタということで、まだパーツ数が多いです。むりやり、布テープで接合しているのですが、PLA樹脂だとわりと剥がれます。

いろいろと経験値はたまったので、弐号機では箱型にして、2パーツで組み合わせる形にしようと考えています。また、手前の肌に当たる部分が、立方体だと整形ずれによって意外と痛いので、丸みを付けて整形した方がよいかなと考えています。とりあえず布テープでごまかしていますが、ちゃんと設計し直そうと思います。

また、今回は大きいものを印刷できるかどうかのテストも兼ねていたので、いきなりフルサイズで印刷してインクを浪費してしまったので、次からは1/8程度の縮小版でプロトタイピングした後、フルサイズで作ろうと思います。

トータルでは、わりとスムーズに作れて面白かったです。CubeのファームウェアアップデートでアプリがSegfaultを出したり、Wifi設定を記憶してくれなかったり、樹脂がとても高価で一つ作るのに3000円くらいかかったりと、いろいろと不満があるにはあるので、このあたりが時間とともに解決していくとよいなと思います。



(2014/8/20に追記)その後、改良を重ねまして、四号機でようやく完成しました。最終バージョンのモデルデータをThingiverseに上げましたので、ご自由にご利用下さい。

Google Cardboardを500円で作ってみた

GoogleのダンボールVRゴーグル、Google Cardboardのデザインファイルが公開されたので、作ってみました。

IMG_1116

デザインファイルは、公式サイトのCardboard Design FileにPDFの形で入っています。PDFのサイズはアメリカのレターサイズで215.9mm x 279.4mmですが、A4でも問題なく作れました。これを、プリンタで印刷するのですが、うちにはプリンターがないので、ネットワークプリントを使ってコンビニで印刷しました。

IMG_1111

次に、印刷したレイアウトを、Amazonのダンボールに貼り付けます。後は、ハサミとカッターを使って、切り抜いていきます。1時間くらいかかります。

IMG_1112

ダンボール以外には、レンズとマグネットとマジックテープが必要なので、秋葉原のダイソーで調達してきました。レンズはルーペから簡単に分解して取り出せました。分解したら二枚入ってたので、2つ買う必要はなかったです。マグネットは、ハードウェアボタンとして使います。

IMG_1114

マジックテープはスマートフォンを簡単に取り出せるようにするために必要です。

完成したら、Google Cardboardのアプリで楽しみます。端末はGalaxy NexusとNexus5で試しましたが、磁気センサーの位置の問題か、Galaxy Nexusだとマグネットボタンの反応が悪いので、Nexus5の方が良かったです。

実際、使ってみると、想像以上のクオリティで、Oculusを初めて使った時と同じ衝撃を受けました。全視界に広がる立体視の映像は素晴らしく、Google Earthで空を飛ぶのはもちろん、3Dの仮面のオブジェクトを立体でただ眺めるだけで面白いというのはすごいです。総製作費500円にもかかわらず、Oculusとほとんど同じ感動を味わえるわけで、プラスチックで製品化したら、一気にVRが普及するかもしれません。

Oculusで動くファンタジーRPGっぽいデモを作成しました

Oculus Riftで動くファンタジーRPGっぽいデモを作成しました。WindowsでもMacでも動きます。

dragon
操作方法は以下です。

アクションIDキーボード操作ジョイパッド操作
移動LeftStickカーソルPS3の左スティック
視点移動RightStickマウスPS3の右スティック
攻撃Fire1左コントロールPS3の□ボタン
ジャンプJumpスペースPS3のxボタン

demo
終了はESCです。Windows版は問題ないですが、Mac版は終了に失敗してしまうことがあるので、その場合は、Command+Option+ESCで強制終了して下さい。

water

デモをダウンロードする(Windows/Mac)

UnityでOculus Riftに対応する

Oculus Rift SDKにはUnity用のPrefabが含まれているため、簡単にUnityアプリをOculus対応にすることができます。

まず、Oculus Riftのデベロッパーサイトでデベロッパー登録を行い、Unity 4 Pro Integrationをダウンロードします。

oculus


中に含まれているOVRフォルダをUnityのプロジェクトにドロップします。Prefabsフォルダに含まれているOVRPlayerController.prefabをHierarchyにドロップします。これで終わりです。

ovr


OVRPlayerController.prefabは、OVRCameraController.prefabを内包しています。カメラだけを使いたい場合はOVRCameraController.prefabを、カメラの移動まで行いたい場合はOVRPlayerController.prefabを使用します。既存アプリを置き換える場合、現在使用しているカメラをOVRPlayerController.prefabで置き換えるのが簡単です。

test


以上の操作で、自動的にOculus用のレンダリングが行われます。Oculusを接続している場合は湾曲してレンダリングされ、接続していない場合は普通にレンダリングされます。

尚、HDMI分配器を使用した場合、Oculusを認識できず、正常にレンダリングできないので注意して下さい。Oculusのライブラリ内部で、HMDが接続されているかどうかのチェックが行われています。

また、Oculusのライブラリは、内部で、WindowsのDLLと、Mac OSXのbundleを呼んでいるため、Unity Proのライセンスが必要です。
Search
Profile

abars

アプリとWEBサービスを開発しています。最近はUnityとGAE/pyが主戦場。

ブラウザ向けMMOのメトセライズデストラクタ、イラストSNSのイラストブック、東証の適時開示情報を検索できるTDnetSearchを開発しています。

かつてエンターブレインのTECH Win誌でATULADOを連載しました。

サイト:ABARS
Twitter:abars
Github:abars

Twitter
TopHatenar
HotEntry
Counter

アクセス解析付きカウンター。あなたのBLOGにもどうですか?登録はこちらから。

TOP/ BLOG/ LECTURE/ ONLINE/ RUINA/ ADDON/ THREAD/ METHUSELAYZE/ IPHONE/ MET_IPHONE/ ENGLISH/ RANKING