Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

勉強会レポ : Standalone VR Meetup #02

勉強会のレポート(メモ)です。
参加したのはこちら、「Standalone VR Meetup #02」
会場はDMMさんです。

standalone-vr.connpass.com

ハッシュタグ : #すたみと

f:id:Raspberly:20190619013148j:plain

 

 

 

 

Standalone VR Meetupとは
スタンドアロンVRの知見共有や作成したアプリの自慢を行う会です。

会場提供はDMMさん。

勉強会の内容はいっぱいツイートしてください
ハッシュタグは「#すたみと」です
#るきべんをパクリました

 

 

タイムスケジュール

時間 内容 発表者(敬称略)
19:40- ①東京クロノスのQuest対応についての話(仮) @ookumaneko_XD
19:48- ②Oculus Questでお餅をつこう!! @nkjzm
20:56- ③6DoF Oculus Goの作り方 @gravitino
20:04- ④EXOS_DEMOをOculusQuestで動作させる @MikiSoftWorks
20:12- ⑤リリース済みSteamVRゲームが一瞬でQuestに移植できた話~タイトルはNDA @GONBEEE_project
20:20- ⑥Oculus Questでマリオネットを召喚して遊んでみた @baku_dreameater
20:28- ⑦さよなら満員電車^^Pepperがあればだれでも簡単♪VRテレイグシステムの完全版♡ @pg_nokkii
20:36-20:45 展示者紹介ピッチ  

 

 

展示一覧

タイトル 内容 展示者
VRM Viewer For Oculus Quest VRMを好きに入れ替えかえて、色んな視点から見れるビューワーです。リポジトリ公開中。 @yashinut
② 地球危うしVR 地球を揺らして建物を破壊するゲームを展示します @patsupyon
③ 夢枕VR ハンモック+OculusQuestで日常から離れて癒されるアプリ @NazzTea
④ Mirror OculusRift, OculusGOでリリースしたVR ホラーゲームのQuest移植版 @UnagiHuman
⑤ 点群マトリックス 点群を某マトリックス映画風にして見て回るコンテンツ @koukiwf
⑥ Oculus Quest - 触覚デバイスEXOS連携デモ XR用触覚デバイスEXOSをOculus Questと連携させ、完全ワイヤレスな環境で自由にバーチャルオブジェクトに触れるデモをご紹介させて頂きます @yamaulab
⑦ 歩ける全天球動画 for Oculus Quest 定点撮影した全天球動画と形状を組み合わせることで、実写映像の中を歩き回ることが出来ます。 @waffle_maker
⑧ ペンギンスレッド ペンギンを使ったレースゲームです @chocogake_san
⑨ ジュン少年の事件簿(仮) Oculus Go + アナログな皆で遊ぶゲームブックっぽいゲーム @ookumaneko_XD

 

 

 

 

LT1. 東京クロノスのQuest対応についての話

東京クロノスとはVR向けのアドベンチャーゲームです

今日は、Quest対応の話をします
・デザイン 審査対応
・実装はおまけで話します

Questはストア対応が大変ですが、その話はしません

QUESTの6Dofはいいぞ

VR内で手を出してと言われました、ゲームデザイン的に出したくありませんでしたがしかたなく出しました。

やった対応としては一定時間動かなかったら手を消すといった処理を挟みました。
現状ストアに出すにはQAのテストが入りますが、ゲーム内で手が追従しないという指摘を受けました。
これは「仕様です」で押し切った。このやり取りを複数回・・・

小話

Oculus側にも手がいらない派の人が多少いたらしい

実装面

SDKを最新にしました。
unity2018.2.21以上でないとストアにリリースできない。
OVR Metrics Toolを入れました。
もしかしたらCPUスロットリンクが対応できないかもしれない。
基本Goと同じと考えた方がいいです。

 

 

 

 

LT2. # Getting started with Quest

スライド
# Getting started with Quest - Speaker Deck

 

タイトル変えました。
Questでどんな感じで開発できるのかという話をします。
徹夜してタワーディフェンスを作りました、褒めて♡

開発の基本

この記事をみてください

framesynthesis.jp

 

開発でかゆい点

ケース1 有線接続がめんどくさい

リモートビルドに対応しています


ケース2 エディタ上で確認したい

おすすめはRiftを使うこと
Questでやる場合はALVRでやるのがいいでしょう。

ケース3 Goとどう違うか

Goから移植するのは超簡単
そのままいけます
Oculus Integratin1.37以上であればいい

 

開発Tips

Oculus Integrationは超便利

基本的な機能は全て揃っています

Google Polyが簡単で便利

トゥーン調の3Dモデルが入手できます
地形はObject2Terrainで作っています

kan-kikuchi.hatenablog.com

ルームスケールが楽しい

どこまで動けるかは予め設定してあげるといいよ。

 

 

 


LT3. 6DoF Oculus Goの作り方

情報量が多いのでスライドをどうぞ(まだ公開されていません)

されてました。

www.slideshare.net

 

 

 

 

LT4. EXOS_DEMOをOculusQuestで動作させる

drive.google.com

EXOSとは何か

VR空間で何かに触った時にモーターを動かしてフィードバックを与えるVRバイスです。
従来はPC向けに作っていました。Quest向けのビルドはすぐに終わりました。

困ったこと

インストールできない

AdbをAPIレベル7.1に上げたら治りました

Editorでデバッグがめんどう

PC向けHMDでテストしました

BlueTooth機能

Bluetoothの機能自体は入っています
権限が必要です、権限をもつアプリから開きましょう

ライブラリの紹介

一つで環境で複数のデバイス向けの開発をできるようにしたい
EXOS SDKなどを提供しています

 

 

 

 

LT5. リリース済みSteamVRゲームが一瞬でQuestに移植できた話~タイトルはNDA

スライド

drive.google.com

内容が濃いのでスライドをご覧ください

Quest用に音ゲーを移植した話

コントローラーの角度

Touchの新型タッチはハンドガンのグリップを握った時に綺麗に表示されるようになっている。
x軸だけ60回転させるといい感じになります。

振動のプレゼンス

Steamは使いにくい。
OculusはAudioClipから波形に合わせて振動させる。
効果音と振動が一致して気持ちいい。

公式PostProcessingStackがとても重い

AndroidとStandaloneVRに対応している軽いポストエフェクトが欲しい。
有料アセットのSleapRenderがオススメ。

assetstore.unity.com公式ではVRサポートしてないと明言されていますが動きました。
今でこそ有料ですが、一時期無料期間もありました。

www.asset-sale.net

Android VideoPlayerが重い

いろいろ対策をしたが動画を使わないのが一番。
AVProを使うという手もある。

 

 

 

 

LT6. Oculus Questでマリオネットを召喚して遊んでみた

スライド
Oculus Questでマリオネットを召喚して遊んでみた - Speaker Deck

具体的にやった内容について
ハンドトラッキングの話

マリオネットは何か

いろいろありますが、今回は完全に糸で動かすタイプ
市場が小さく、マリオネット自体が結構高いためVRで作りました。

実装の話

Obi Ropeというアセットを使いました。
マリオネットとTouchの対応付け。

qiita.com

今後やりたいこと

物理シミュレーション
ぬいぐるみ系モデルの検討
IKの併用
マリオネットを等身大、巨大化して同期表示

 

 

 

 

LT7. さよなら満員電車^^Pepperがあればだれでも簡単♪VRテレイグシステムの完全版♡

情報量が多いのでスライドをどうぞ

www.slideshare.net

 

 

 

 

タイムライン

 

 

 

 

展示会

f:id:Raspberly:20190619013216j:plain

f:id:Raspberly:20190619013208j:plain

f:id:Raspberly:20190619013200j:plain

 

 

 

 

 間違っている箇所、消してほしいツイートがありましたらコメントにお願いします。

【Oculus Quest開発メモ】離れた場所にある物を掴む Distance Grabber & Grabbable編【Unity】

今回はOculus Questの開発ネタをやっていきます。
内容的にはOculus Rift Sなどにもそのまま応用できるかと思います。

 

Oculus Touchコントローラーで離れた場所にあるものを掴む方法について解説します。
プレイエリアが狭い時や、座ったままプレイさせたい時など自由に動き回るのが困難な時に役立ちます。

他にも、机から床に落ちてしまったオブジェクトを拾う時などプレイヤーの負担を軽減できます。

f:id:Raspberly:20190616202258p:plain

 

 

 

開発環境

Windows 10

Unity 2018.4.1f

Oculus Integration ver1.37

Oculus Quest

 

 

先行研究

www.youtube.com

 

 

セットアップ

前回の記事をあらかじめ見ておいてください。

raspberly.hateblo.jp

前提として、Project内にAssetStoreからOculus Integrationをインポートしておく必要があります。


 

 

サンプルシーンの確認

Assets/SampleFramework/Usageに様々なサンプルシーンがあります。
離れた物を掴むサンプルシーンはDistanceGrabになります。
学習や挙動の確認にとても有益です。見てみましょう。

f:id:Raspberly:20190610220845p:plain

 

実行してみるとこんな感じになります。

f:id:Raspberly:20190610225504g:plain

 

 

Oculus Integration 1.42で修正されました

ちなみにこのサンプルシーンには深刻なバグが存在しています
それは物を掴んだ時にPlayerが吹き飛ばされることです。

f:id:Raspberly:20190615234528g:plain



原因はGrabbableとPlayerの衝突のようです。

 

 

サンプルシーンのバグ修正

このバグを修正する方法を載せておきます。

PlayerにはCharacterControllerがくっついています。

f:id:Raspberly:20190610231445p:plain

 

このColliderとGrabbableのColliderが接触しないようレイヤーを分けます。
[Player][Grabbable]レイヤーを新しく作成します(名前はなんでもいいです)

f:id:Raspberly:20190611000330p:plain

シーン内にあるOVRPlayerControllerはPlayerレイヤーにしましょう。

f:id:Raspberly:20190611000531p:plain

この時、子オブジェクトのレイヤーは変えないでください(理由は後述)

 

その後、サンプルシーンの中にあるDistanceGrab~~~と名前のつく掴みたいオブジェクトを全てGrabbableレイヤーにします。

f:id:Raspberly:20190611001104p:plain

f:id:Raspberly:20190611001140p:plain

 

最後にProjectSettingのPhysicsからPlayerとGrabbableのチェックを外しておきます。

f:id:Raspberly:20190611001453p:plain

 

これでPlayerが吹き飛ばされることなくシーンが動きます。

f:id:Raspberly:20190615234611g:plain

 

 

他には、CharacterControllerを切ってしまうという手段もあります。

f:id:Raspberly:20190616081709p:plain



 

 

 

 

 

 

 

主要コンポーネント

こちらもOVR Grabber&Grabbable同様Oculus側でコンポーネントが用意されています。
そちらを使っていきましょう。
これらはインポートしたOculus Integrationの
Assets/Oculus/sampleFramework/Core/DistanceGrab/Scriptsにあります。

DistanceGrabber

こちらは物を掴む側、つまり手につけるコンポーネントになります。

DistanceGrabbable

こちらは物を掴まれる側、つまりオブジェクト側につけるコンポーネントになります。

Grab Manager

こちらは物を掴む範囲を決めるコンポーネント、DistanceGrabberを使うのに必須です。

 

 

 

DistanceGrabber

DistanceGrabのシーンにある、DistanceGrabを見てみましょう。

f:id:Raspberly:20190611213013p:plain

f:id:Raspberly:20190611213643p:plain

OVR Grabberコンポーネントがついているのがわかります。
手にあたるオブジェクトにはこのコンポーネントが必要です。
(Rigitbodyも必要)

 

このコンポーネントOVR Grabberを継承して作られています
そのため使い方やインスペクターはOVR Grabberに規準しています。

 

 

インスペクターパラメーター(追加分)

とても多いです。掴める対象物のことをターゲットと呼称します。

FocusColor

 掴むオブジェクトをアウトラインする機能、色を指定できる。

Spherecasrt Radius

ターゲットを見つけるSpherecastの半径。
Spherecastを使用している場合、この値が大きいほどターゲットを見つける範囲が大きくなる。

No Snap Threshhold

オブジェクトとの距離がこの値より近い場合は、通常のGrabberと同じように掴みます。
この値より離れている場合は手元に引き寄せます。

Use Spherecast

Spherecastを使ってターゲットを見つけるかどうか。

Prevent Grab Through Walls
Object Pull Velocity

離れたオブジェクトを掴む時に、手元に飛んでくる速度。
例を用意しました、左手が速度2、右手が速度10です。

f:id:Raspberly:20190616214619g:plain

Max Grab Distance

掴むことのできるオブジェクトの範囲。

Grab Objects In Layer & Obstruction Layer

掴むターゲットにするレイヤーの数字。

Player

Playerのオブジェクト、子オブジェクトからGrabManagerのSphereColliderを参照するのに使う。

 

 

 

 

DistanceGrabbable

このコンポーネントOVR Grabbableを継承して作られています
そのため使い方やインスペクターはOVR Grabbableに規準しています。

 

特に変更点はありません。
通常のGrabbableと同様に、近づいて掴む機能はそのまま使うことができます。

 

 

 

 

GrabManager

これはGrabする範囲を決定するコンポーネントです。これがないとGrabberが動きません
SphereColliderとセットで扱います。(要isTrigger)
サンプルシーンではOVRPlayerControllerの子オブジェクトになっています。
必ずプレイヤーの子オブジェクトにする必要があります

 

Outline Colorから、範囲内のオブジェクトにアウトラインをつけることができます。

f:id:Raspberly:20190616163827p:plain

 

SphereColliderのRadiusの値を変えるだけで簡単に範囲を設定できます。

f:id:Raspberly:20190616163746p:plain

GrabManagerのスクリプト内ではCollider型で参照しているのでSphere以外のColliderも使うことができる・・・
かと思いきや、実はDistanceGrabberがSphereCollider型でGetComponentしているのでSphereしかだめみたいです。

 

 

 

 

実際に掴めるオブジェクトを置いてみる

では実際に掴むことができるオブジェクトをテーブルの上に新しく作ってみましょう。
今回もユニティちゃんを使用します。

f:id:Raspberly:20190616173300p:plain

 

Hierarchyビューでは、Grabbableをアタッチする用に空のオブジェクトを作り、その中にユニティちゃんを格納する構造にします。

f:id:Raspberly:20190616172508p:plain

 

空のオブジェクトのインスペクターはこんな感じです。

f:id:Raspberly:20190616172323p:plain



前回とほとんど同じですが注意すべき点が2つあります。

Mesh Renderer

OVR Grabbableと違い、MeshRendererコンポーネントは必須です
Grabbableをアタッチするオブジェクトに必ずつけましょう。
すでに何らかのRendererがついていれば必要ありません。

Rigidbody Collision Detection

RigidbodyのCollision DetectionはContinuous Dynamicにしないと掴むことができません

f:id:Raspberly:20190616173031p:plain

 

 

 

これだけで準備完了、実際に動かしてみましょう。
無事掴むことができ、投げることもできました。

f:id:Raspberly:20190616201442g:plain

 

 

 

 

 

 

まとめ

離れているオブジェクトを掴む時はDistanceGrabberコンポーネントを使う

 手っ取り早く用意するのであれば、
Assets/Oculus/SampleFramework/Core/DistanceGrab/Prefabsにあるプレハブを使うのがおすすめ。

掴まれるオブジェクトにはDistanceGrabbableを使う
DistanceGrabberを動作させるにはシーン上にGrabManagerを設置する

 

 

参考文献

DistanceGrab Sample Scene

Distance Grab Sample Now Available in Oculus Unity Sample Framework | Oculus

 

 

 

次回は、掴みたいオブジェクトにクロスヘアを表示したり、
演出面についてやっていきます。

 

 

他間違っている箇所、不明な点、わかりにくい点がありましたらコメントにお願いします。

【Oculus Quest開発メモ】デバッグログをシーン空間内に出す OVR Debug Console編【Unity】

今回はOculus Questの開発ネタをやっていきます。
内容的にはOculus Rift Sなどにもそのまま応用できるかと思います。

 

デバッグログなどの数値を、VRシーン空間に配置して表示する方法について解説します。

f:id:Raspberly:20190610005827p:plain


 

 

 

 

開発環境

Windows 10

Unity 2018.4.1f

Oculus Integration ver1.37

Oculus Quest

 

 

 

先行研究

Oculus Questを開発されている多くの方が実感していると思いますが、
Questはデバッグ作業が非常に大変です。
Unity Editorのプレイボタンから実行できないので、毎回ビルドして実機で動かす必要がでてきます。
ですのでRift Sで開発をしたり、ALVRを使うと捗ります。

joytokey.net

bibinbaleo.hatenablog.com

 

 

これとは別にシーン空間内にインスぺクターの数値を表示してデバッグされている方もいました。

www.youtube.com

今回はこちらを試してみます。

 

 

 

 

セットアップ

前回と同様、基本的なセットアップをしておきましょう。
こちらのブログ様がとてもわかりやすい解説記事を投稿なさっています。

cycling.hateblo.jp

Oculusの開発には「Oculus Integration」というアセットが必須です。必ずインポートしましょう。

assetstore.unity.com

細かい設定は上のブログを参考にしてみてください。

 

 

 

 

 

OVR Debug Console

OVR Grabberのように、Oculus側でデバッグ用のコンポーネントが用意されています。
その名も「OVR Debug Console」です。
Assets/Oculus/VoiceMod/Scrips/Helpersの中にスクリプトがあります。

f:id:Raspberly:20190609234457p:plain

 

こちらをシーン内にある空のゲームオブジェクトにアタッチします。
するとインスペクターにはこのように表示されます。

f:id:Raspberly:20190609234729p:plain

 

インスペクターパラメーター

Max Message

 メッセージの最大表示数。表示数とありますが厳密には行数です。
デフォルトだと15行表示され、それ以降は古い順から消されていきます。

Text Msg

 メッセージを表示するためのText。つまるところUGUIのTextのこと。

 

 

Text Mesh Pro対応

UGUIのTextよりもText Mesh Proで出したい場合もあるかもしれません。
その場合、OVR Debug Consoleのスクリプトを書き換える必要がでてきます。
Text Mesh Proはプロジェクトにインポートしておきます。

 

 

Textの表示部分も書き換えましょう

 

 

 

 

 

 

実際に表示してみる

実際に使ってみましょう。
今回は試しに特定のOVR GrabbableがGrabberに掴まれているかどうかを表示してみます。
以下のテスト用のスクリプトを用意しました。
OVR Debug Consoleはstaticなオブジェクトなことに気を付けましょう。

 

 


インスペクターでTextまたはText Mesh Proを設定しておきましょう。
VRのUIの場合、TextにしろText Mesh Proにしろ、
CanvasのRender ModeがWorld Spaceになっていることが前提です。

f:id:Raspberly:20190610005436p:plain

 

無事表示できました。
懐中電灯を持っている時はTrueと表示され、持っていないときはFalseと表示されます。
Debug.Logと同様に関数を呼ぶだけで利用できるのでかなり手軽ですね。

f:id:Raspberly:20190610005506g:plain



 

 

まとめ

シーン空間上でデバッグログを出す場合はOVR Debug Consoleコンポーネントを使う。
当然Textも必須です。

 

 

 他間違っている箇所がありましたらコメントにお願いします。

【Oculus Quest開発メモ】物を掴む、物を投げる OVR Grabber & Grabbable編【Unity】

今回はOculus Questの開発ネタをやっていきます。
内容的にはOculus Rift Sなどにもそのまま応用できるかと思います。

VR開発の基本の基本、Oculus Touchコントローラーで物を掴み、物を投げるところまでやってみます。

f:id:Raspberly:20190608234840p:plain



 

 

 

 

先行研究

note.mu

 

開発環境

Windows 10

Unity 2018.4.1f

Oculus Integration ver1.37

Oculus Quest

 

 

 

セットアップ

基本的なセットアップをしておきましょう。
こちらのブログ様がとてもわかりやすい解説記事を投稿なさっています。

cycling.hateblo.jp

 

Oculusの開発には「Oculus Integration」というアセットが必須です。必ずインポートしましょう。

細かい設定は上のブログを参考にしてみてください。

 

追記 2020/02/18

当ブログでもまとめました。

raspberly.hateblo.jp

 

 

 

 

主要コンポーネント

物を掴んだり、投げる動作はOculus側でコンポーネントが用意されています。
そちらを使っていきましょう。

これらはインポートしたOculus Integrationの
Assets/Oculus/VR/Scriptsにあります。

OVR Grabber

こちらは物を掴む側、つまり手につけるコンポーネントになります。

OVR Grabbable

こちらは物を掴まれる側、つまりオブジェクト側につけるコンポーネントになります。

 

 

 

サンプルシーンの確認

Assets/SampleFramework/Usageに様々なサンプルシーンがあります。
物を掴むサンプルシーンはAvatarGrabになります。
学習や挙動の確認にとても有益です。見てみましょう。

f:id:Raspberly:20190608164841p:plain

 

実行してみるとこんな感じになります。

f:id:Raspberly:20190608180414g:plain

 

【追記】 2020/02/18

AvatarGrabシーンが削除されました。詳しくはこちら。

raspberly.hateblo.jp

 

 

 

 

 

OVR Grabber

AvatarGrabのシーンにある、AvatarGrabberを見てみましょう。

f:id:Raspberly:20190608213450p:plain

f:id:Raspberly:20190608215714p:plain


OVR Grabberコンポーネントがついているのがわかります。
手にあたるオブジェクトにはこのコンポーネントが必要です。
(Rigitbodyも必要)

インスペクターパラメーター

GrabBegin

 オブジェクトを掴むときのトリガーのしきい値です。(0~1の範囲)
この値が高ければ軽い押し込みで掴むことでき、
この値が低ければ深く押し込まないと掴むことができないようにできます。

GrabEnd

 オブジェクトを放すときのトリガーのしきい値です。(0~1の範囲)
この値が低いほど、トリガーをしっかり離さないとオブジェクトは掴まれたままです。

Parent Hold Object

 falseの場合、掴んだオブジェクトはFixedUpdateにて移動します。

Grip Transform

 掴んだオブジェクトの移動先を指定します。おおよそ手の握った位置になります。
ここが設定されていないと掴もうとしても反応しません。(1敗)

Grab Volumes

 掴む時の当たり判定、このコライダーが大きければ大きいほど掴める範囲が広くなります。

Controller

 右手の場合はOVRInput.Controller.RTouch。
左手の場合はOVRInput.Controller.LTouchとしましょう。

Parent Transform

 自身の親のTransformが入ります。
手動で設定されていない場合はScript側で勝手に設定されるのでさわる必要はありません。

 

他のプロパティ

OVRGrabbable grabbedObject

 現在掴んでいるオブジェクトを取得
オブジェクトを取得といってもOVRGrabbableなので他のコンポーネントを取りたい場合はGetComponentする必要がある。
gameobject自体を取りたい場合は、grabbedObject.gameobjectで取れる。

 

 

 

 

 

 

 

OVR Grabbable

お次はCubeの方を見てみましょう。

f:id:Raspberly:20190608224838p:plain

OVR Grabbableコンポーネントがついているのがわかります。
掴むオブジェクトにはこのコンポーネントが必要です。
(RigitbodyとColliderも必要)

 

インスペクターパラメーター

Allow Offhand Grab

 falseの場合掴めなくなります。
今は掴ませたくないオブジェクト、状況に応じて掴めたり掴めなかったりさせたい時に外部から変えるといいでしょう。

Snap Position

 Trueの場合、掴まれたときオブジェクトの位置はSnap Offset(後述)と一致するように移動します。
剣や銃など、明確に持ってほしい箇所が決まっている時に設定します。

Snap Orientation

 Trueの場合、掴まれたときオブジェクトの角度はSnap Offset(後述)と一致するように移動します。
こちらもPositiobnと同様、この辺りは別途記事で解説します。

Snap Offset

 掴まれたときに移動するGrabberからの相対的な位置です。
何を言っているかわからない?この辺りは別途記事で解説します。

Grab Points

 掴まれたときの接触点。Scriptを見てみるとGrabber側で掴むときの接触判定に使っているようです。

 

他のプロパティ

bool isGrabbed

 つかまれているとtrueを返す
Grabberが現在掴んでいるオブジェクトを把握するのに使う

OVRGrabber grabbedBy

 このオブジェクトを掴んでいるOVRGrabberを返す
掴んでいるのが右手か左手かを判別するのに使えるし、掴んでいる手の状態を取得できる

transform grabbedTransform

 オブジェクトが掴まれた瞬間の位置を取得する
その場所になんらかのエフェクトを置いたりするのに使うのかも

rigitbody grabbedRigidbody

 オブジェクトをつかむために使用されたコライダーのrigidbody

 

 

 

 

実際に掴めるオブジェクトを置いてみる

では実際に掴むことができるオブジェクトをテーブルの上に新しく作ってみましょう。
今回はユニティちゃんを使用します。

f:id:Raspberly:20190608231347p:plain

 

インスペクターはこんな感じです。
OVRGrabberのScriptの中では衝突判定にOnTriggerを使っているのでIsTriggerにチェックを入れたいところですが、別に入れなくても動作します。
サンプルシーンのキューブにもチェックは入っていません。

f:id:Raspberly:20190608231544p:plain


これだけで準備完了、実際に動かしてみましょう。
無事掴むことができ、投げることもできました。

f:id:Raspberly:20190608233843g:plain

 

 

 

 

まとめ

オブジェクトを掴むときはOVR Grabberコンポーネントを使う

 手っ取り早く手を用意するのであれば、
Assets/Oculus/SampleFramework/Core/AvatarGrab/Prefabsにあるプレハブを使うのがおすすめ。

掴めるオブジェクトにはOVR Grabbableコンポーネントを使う

 

 

 

 

 

あとがき

プロパティやパラメータの説明は公式リファレンスやソースコードのコメント文から書き起こしました。
もしかしたら、変な訳になっているかもしれません、お気づきの点がございましたらコメントにお願いします。

 

公式リファレンスはこちらです。記事執筆時はバージョン1.37です。
OVR Grabber: https://developer.oculus.com/reference/unity/1.37/class_o_v_r_grabber/

OVR Grabbable: https://developer.oculus.com/reference/unity/1.37/class_o_v_r_grabbable/

 

 

他間違っている箇所がありましたらコメントにお願いします。

勉強会レポ : 【Unity / .NET Core】 MagicOnion勉強会

勉強会のレポート(メモ)です。
参加したのはこちら、「【Unity / .NET Core】 MagicOnion勉強会」
会場はドワンゴさんです。

connpass.com

ハッシュタグ#MagicOnion

 

 

f:id:Raspberly:20190604235120j:plain

 

 

動画はこちらから。

www.youtube.com

 

 

 

 

 

 

 

 

今回は実演が多い箇所があるので別途スライドと動画を見てください。

#1. MagicOnionライブコーディング+α

 

 

 


 

#2. The Patterns of MagicOnion

MagicOnionとは

gRPCベースでなんでもできるネットワークエンジン
できるのはサーバーを通したRPC
RPCとははネットワークごしにメソッドをよぶこと

MagicOnionは究極の土管

どこまでも応用がきいてなんでもできる。

重要なのはサーバープログラムを透明にしないこと
どっちも大事です。クライアントだけで完結などはナンセンス。

クラウドサーバー間のRPCをどれだけ書きやすくできるかということをMagicOnionは追求しています。

P2Pじゃない

P2Pは結構複雑
サーバーを通して通信すると考えるだけで結構シンプルになります。

実装パターン

サーバーとクライアントをどうシェアするかがはまりどころ
コピペで済ませていいんです

ホスティング

ホスティング用のパッケージが専用に用意されています
これを使えば全部やってくれます
ASP.Net Coreなど標準のしくみに乗っかっています

コンテナカット

コピペでOKです

デプロイ

CIを使えばおおむねOK(CircleCIをオススメ、いい感じに処理してくれます)
ここも意味わかんなくてもコピペすればOK

リアルタイムサーバー

ストリーミングハブを使いましょう

マッチングサービスは自分で作る必要があります(Open Matchがおすすめ)
ただ現状微妙、自前で作った方がいいでしょう。
MagicOnionは外部のミドルウェアやサービスに全乗りできるのがいいところ。
他のシステムに乗っかって、組み合わせて作ることができます。

これからのロードマップ

Pure C#
コードジェネレートの改善
サーバーサイドのゲームループ
テレメトリ改善
サーバーレス対応

まとめ

オレオレフレームワークにしないようにしています
UniRxのようにほかのところでも使える知識を得られるようにしたい

 

 

 

 

#3. 明日から使えるMagicOnion

MagicOnionはHTTP/2を使っています(前は1を使っていた)
2はコネクションを張りっぱなし
指定のアドレスを聞きに行くのではなくgRPCなどのライブラリを使います
gRPCは見慣れない部分が多いがMagicOnionならC#の構文で書くことができます

MagicOnionの使用目的

Unity以外でも使えます、デスクトップアプリでも

MagicOnionはPhotonWireをベースに洗練されたものです
それぞれの特徴を生かして使っていきましょう

MagicOnionの強み

・定義がC#で完結します
・VisualStudioのサポートを受けることで実装速度が向上します
・.NET Core対応
・Unity対応
・作っている人が日本にいます

MagicOnionの弱み

・実績がまだない
・会社で導入するには実績がないとつらい
C#がきらいな人にとってはつらい
・ノウハウの情報が少ない

MagicOnionの勘違い

・通信は遅いということはない
モバイル用だとどうやってもかかる
・サーバーサイドC#は遅いということはない
・全部C#なら実装速度早いのでは
MagicOnionで得られるのはサーバー・クライアントの透明性
両方C#なのでクライアントエンジニアがサーバーを読みやすい
C#は実装の速度は速くなるがリリースの速度が速くなるというわけではない

UniRxとMagicOnion

・一部コンポーネントが被る
・MVRPを使うならHub/ReceiverはModelが持つべき
Hub/Receiverはクライアント視点でどこで使うのかを見てわけるとよい

チームの話

サーバーとクライアントが同じ言語ならチームメンバーが両方やるべきか?
サーバーはサーバーで専用の知識が必要だったりする、ただチーム構成は広がります

Unityエディタ拡張

gRPCがよくUnityを殺します
gRPCがゾンビ化するので寿命管理はしっかりやりましょう

リアルタイム通信

多少の遅れが認められるもの
毎フレーム状態が変わるものはオンメモリでやったほうが楽

mocとmpc

メッセージパックのresolverの作成
本来はリフレクションを使うところだが、IL2CPP向けにこういうのがあります

まとめ

こういうプロジェクトを作りました

 

 

 

 

#4. MagicOnionでの共通処理の挟み方

サーバーサイド

2つやりかたがあります
・MagicOnionFilter
・gRPCInterceptor
どっちもgRPCの前後に処理を挟むものです

どっちを使えばいいのかというと、それぞれできることが違います。

クライアントサイド

gRPCでやるしかないです
戻り値がasyncじゃないので作る必要があります

エラーハンドリング

gRPCではAggregateExceptionが発生します
ただしInterceptorを複数重ねるとその数だけラップされ取り出しづらくなってしまう
そのため1クラスにまとめて書いた方がいいです

リトライ処理

リトライをする方法がなさそうなので拡張メソッドをつくる必要があります

まとめ

サーバーは要件に合うほうを使いましょう
クライアントはgRPCのみ
できないことは頑張って実装しましょう

 

 

 

 

 

LT1. MagicOnionをContainer化してkubernetesで動かしてNew Relicで監視する

 

 

 

LT2. MagicOnionを使う場合と使わない場合

MagicOnionとgPRCはうまく使い分けようというお話

 

 

 

LT3. リアルタイムなゲームの開発でコンテナを使ってみたら簡単便利で激安だったのでオススメしたい!

リアルタイムなゲームはサーバーでコンテナで動かしましょう
最初はローカルでやっていくとあとからつらくなる

コンテナの敷居は高くない

コンテナ化は簡単
Qittaに記事にしました。

qiita.com

コンテナの起動めんどそう

実際めんどいです
apiで操作しましょう
私はazureを使っています

個人開発だしサーバーにお金かけたくない

コンテナを動かす構成は非常に安い
私の場合だと91円

コンテナは安くて便利で手軽
ぜひ使ってみてください

 

 

 

 

 

 

タイムライン

 

 

f:id:Raspberly:20190605010451j:plain

 

 

 

間違っている箇所、消してほしいツイートがありましたらコメントにお願いします。

Oculus QuestからPCにスクショや録画ファイルを取り込む(Windows)

 

今回はOculus Questのネタをやっていきます。
Oculus Quest内で撮影・録画したデータをPCに取り込む方法について。
ちょっと詰まった個所ですので共有もかねて書き残しておきます。

 

Oculus Quest2版はこちら

raspberly.hateblo.jp

 

 

 

この記事のまとめ

・Oculus QuestはPCに接続するだけでスクショや録画した動画ファイルを確認できる。

・しかし録画した動画ファイルは再生できなかった。

・Windows10の「画像とビデオのインポート」で取り込むと再生できた。

 

 

環境

Oculus Quest
Windows10

 

 

 

Quest内で画像や動画を撮る

Oculus Questでスクショや録画ができることはみなさんご存じかと思います。

f:id:Raspberly:20190602135457p:plain


保存された画像や動画はOculusギャラリーという場所に保存されます。
ここはホーム画面のナビゲーションからギャラリーを選択。

f:id:Raspberly:20190602141819p:plain


内部ストレージ内から全てまとめて表示したり、フォーマットごとに見たりといったことができます。

f:id:Raspberly:20190602141903p:plain



 

 

PCからOculus Questの内部を見る

ではこのOculusギャラリーをPCから見るにはどうすればいいでしょうか?
実はPCに接続するだけでエクスプローラーから参照することができます。

f:id:Raspberly:20190602144143p:plain


この中からいろいろ見ることはできますが、以下のパスのフォルダの中にスクリーンショットなどが保存されています。

PC\Quest\内部共有ストレージ\Oculus

f:id:Raspberly:20190602144408p:plain

Screenshots:スクリーンショット(jpg)などが保存される場所

VideoShots:録画した動画ファイル(mp4)が保存される場所

 

Screenshots

こちらは簡単、中に入っているjpgを開くだけでスクショを見ることができます。
大きさは1024*1024固定のようです。

f:id:Raspberly:20190602144839p:plain

 

 

VideoShots

問題なのはこちら、ここには録画したmp4ファイルが入っていますが、
私の環境だとこちらの動画ファイルを開くことができませんでした。

f:id:Raspberly:20190602145014p:plain

他プレイヤーを試してみても応答なし。


 

 

 

 

解決方法の検索結果

いろいろ調べた結果様々な方法が見つかりました。
私の場合はうまく行きませんでしたが、まずはこちらを試してみるといいかもしれません。

 

mashironote.com

bright-b.com

qiita.com

adbで取り込んだり、Quest搭載の録画機能は使わずミラーリングで録画するなどいろいろあるようです。

 

 

 

 

実際にうまくいった解決方法

私の環境でうまくいった方法ですが、Windows10の「画像とビデオのインポート」機能を使いました。
私自身使ったことのない機能でしたので詳しいわけではありませんが手順を紹介します。

 

まずはエクスプローラーにあるOculus Questのアイコンを右クリックし、
「画像とビデオのインポートを押します」

f:id:Raspberly:20190602152621p:plain

 

すると以下のようなウィンドウがでてきます。この状態のまま「次へ」を押します。
今までの画像、録画ファイルを全て取得したいのなら、「すべての~」にチェックを入れるといいかもしれません。

f:id:Raspberly:20190602152635p:plain

 

次はこの場面になります。
スクショや録画ファイルが保存された日時でグループ化されています。
取り込みたいグループにチェックをいれインポートを押します。

f:id:Raspberly:20190602152705p:plain

 

すると無事PCに取り込まれます。もちろん動画ファイルも再生可能です。

f:id:Raspberly:20190602153607p:plain

f:id:Raspberly:20190602161218g:plain

インポートされたファイルの保存ディレクトリは初期状態だとマイピクチャになるようです。

 

 

 

まとめ

・Oculus QuestはPCに接続するだけでスクショや録画した動画ファイルを確認できる。

・しかし録画した動画ファイルは再生できなかった。

・Windows10の「画像とビデオのインポート」で取り込むと再生できた。

 

これがベストプラクティスなのかはわかりません。
「解決方法の検索結果」の所も参照してみるといいかも。

 

勉強会レポ : Unity道場 5月 〜ゲームジャムで役立つ超速ゲーム企画〜

勉強会のレポート(メモ)です。
参加したのはこちら、「Unity道場 5月 〜ゲームジャムで役立つ超速ゲーム企画〜」
会場はユニティ・テクノロジーズ・ジャパンさんです。

meetup.unity3d.jp

ハッシュタグ : #Unity道場

f:id:Raspberly:20190531000102j:plain

 

 

 

 

実際に手を動かして取り組むワークショップ形式です。
講義の内容はGGJ2019 事前勉強会の2幕目「GGJ企画会議対策講座」と重なる部分があります。
こちらも是非チェックしましょう。

raspberly.hateblo.jp

 

 

この勉強会の動画はTwitchで公開される予定です。

www.twitch.tv

 

 

 

ゲームジャムは時間がない

そのためチーム全員で動いた方がいい、企画に参加できない人がでるのはもったいない。
また、ゲームデザインもやることが多い。

企画職を過信しない

コードもリソースも作らない人がいいゲームの企画を出せますか?(辛辣)
今はプロトタイピングを早くしましょう。企画書や仕様書を書く必要はない。

そもそもゲームとは何か

ルールとゴールのある遊びのこと
では遊びとは何かというと「日常の中でしない行為を発見し、突き詰める過程を楽しむこと」

つまり企画とは

行為、ルールとゴール、表現と家庭を決めること(所説あります)
ただしこの辺に答えはない。
決定的な答えを出せない問題をGGJで検討するのはやめましょう。

 

 

ゲームの何を決めるか

大雑把な話をするとこの3つが結びついてきます。
・テーマと表現
・プレイヤーの行動
メカニクス

ゲームは遊んでもらって初めて完成します。
見た目や面白さ、メカニクス、魅力的な要素を考えていきましょう。

 

 

ワークショップ

実際にワークショップを行いました。
流れとしてはこちら。

f:id:Raspberly:20190531003344j:plain

f:id:Raspberly:20190531003354j:plain

f:id:Raspberly:20190531003412j:plain

f:id:Raspberly:20190531003429j:plain

f:id:Raspberly:20190531003442j:plain






 

各班企画発表

ここからはワークショップで実際に企画したゲームの発表となります。 

1.ブロック崩しタワーディフェンス

f:id:Raspberly:20190531000322j:plain
ブロック崩しタワーディフェンスの融合。
ブロックを全滅させられたら負け、耐え切れたら勝ち。
ブロックはプレイヤーが自由に設置でき、組み合わせも自由。
少ないブロックでクリアしたりなどの実績もあります。

 

2.電車

f:id:Raspberly:20190531000427j:plain
HMDを使うVRゲーム。
電車の中で老人に席を譲るか譲らないかというゲーム。
席をゆずると体力が減る、体力がなくなる前に目的地までにいけるかというゲーム。

 

 

3.愛を撃つ

f:id:Raspberly:20190531000819j:plain

敵を撃っていくTPSゲーム、撃たれた敵は味方になる。
最終的に全てのキャラクターを自軍に取り込んだプレイヤーの勝ち。
形式はバトルロワイアル

 

 

4.引っ越し

f:id:Raspberly:20190531000524j:plain

家具をトラックに投げ込むゲーム。ジャンルとしては物理パズル。
家具が入らないと被害損額が増えていく、これを抑えるゲーム。
家具には形・被害総額の違いがあり、どう入れていくのかという駆け引きがあります。

 

 

5.田んぼレーシング

f:id:Raspberly:20190531000700j:plain

田んぼのコンバインを使ったゲーム、カートがコンバイン。
コンバインが通った後は自分の苗の領域、ここを通ると早くなる、
ただし他のプレイヤーに通られると上書きされる。スプラ的な。
そのため独走状態にはなりにくい仕組み、他にもアイテムやイベントがいろいろあります。

 


6.探検隊

f:id:Raspberly:20190531000732j:plain

走る、集める、隠れるという行動がとれる。
猛獣や罠があり、猛獣を罠に引っ掛けてお宝を集めるゲーム。

 

 

 

 

なぜこういう形でアイデア出しをするのか

発言力に任せず全員のアイデアを出せる。
納得の得る形にできる。
フォーマットが統一されるため公平にできる。

 

一番重要なのはみんなが納得したゲームを作ることです。

 

 

メカニクスの引き出し

引き出しはとても重要、メカニクスを学ぶうえでオススメの本を紹介します。
「3Dゲームをおもしろくする技術」
製本版はもうないらしく電子版のみとなります。

 

 

 

 

懇親会

f:id:Raspberly:20190531001942j:plain

f:id:Raspberly:20190531003520j:plain

 

 

 

 

 

 

 

 

 

タイムライン

 

 

 

 

 

他の方のブログ

lycoris102.hatenablog.com

cz-mirror.hatenablog.com

 

 

 

 間違っている箇所、消してほしいツイートがありましたらコメントにお願いします。