【VR】【イベント】Oculus Connect 6 Meetupに参加してきました

2019/10/11、BINARYSTAR株式会社様イベントスペースにて開催された「Oculus Connect 6 Meetup」に参加してきました。
それについて、ご報告いたします!

イベントの構成

イベントは、次の構成で行われました。

  1. Oculus Connect 6 参加報告
  2. VRトレンド紹介
  3. Oculus 体験会
  4. 交流会

なのですが、いかんせん台風19号直撃前夜。
3,4はごく短時間に省略されました。

Oculus Connect 6 参加報告

f:id:s44511173:20191013190810p:plain

Oculus Connectとは、年2回(5月と10月だったかな?)にシリコンバレーで開催されるFacebook公式のOculusイベントです。
 マークザッカーバーグ氏も登壇したとのことでしたが、すみません、無知な私はどなたか存じ上げませんでした・・・。FacebookのCEOだったのですね。

 

f:id:s44511173:20191013191554p:plain

来春以降にもOculusQuestのソフトバージョンアップのみで実現されるハンドトラッキング機能についても、紹介があったようです。
いやー、これ本当に楽しみですよね!
この後紹介されたビジネス向けVRでは、ハンドトラッキングが非常に好評だったようです。なんてったって、ゲーマーじゃない方にコントローラの説明が不要になったわけですから!!(笑)

ビートセイバーやる時にコントローラをぶん投げそうになるんですよ。なので、私もコントローラが不要になるのは非常にうれしいです。

 

f:id:s44511173:20191013192043p:plain

そのビートセイバー開発者の方が、赤いTシャツの登壇者の方。
よーくご覧になってください。Tシャツのプリントwww
左に映っている方も、何かの開発したすごい人(すみません、大事なところ失念)なようです。その方が会場を徘徊されていて、フランクに参加者の質問等に答えていたとのことでした。
そんなイベントなので、次回はぜひ皆さんもご参加してみては?と登壇者の方がおっしゃられていましたが、英語というドデカイ壁があるやん・・・。あと費用とかもさぁ・・・。

OculusQuestのアップデート

f:id:s44511173:20191013192913p:plain

OculusQuestの今後のアップデートについても発表がありました。

PC用だったOculus RiftのアプリをQuestでも使えるようになる機能です!!
これでソフトの幅が大きく広がりますね。
PCとQuestをType-Cで接続するわけですが、Unityエディタでのデバック実行もできるようになったりするのでしょうか。
個人的な話ですが、ALVRで実行するには家のWi-fi環境がヨロシクなくて・・。
いずれ変えなければと思っています。

なお、Riftと全く同等の体験ができるわけではなく、だいたい80%くらいの実現度だそうです。いずれはType-CではなくWi-fiでも実現したいとのことでした。
今はエンコード/デコードでどうしても遅延が発生するとのことです。

ハンドトラッキング

前述の通りです。

VRトレンド

Half Dome

f:id:s44511173:20191013194316p:plain

可変焦点を実現した次世代VRバイスです。
可変焦点とは、焦点を当てているものはハッキリ見えるけれど、それ以外のものはぼやけて見える機能のことです。
現時点のVRでは焦点を当てていようが当てていまいがハッキリ見えてしまい、それが違和感として残ってしまっています。
これが解消できたら、かなり現実に近い体験ができるのでしょう!

Half Domeは現時点で3まで開発が進んでいるそうです。
普及を考えると、Quest同様の5万円が上限とのこと。なんて太っ腹!!

Hyper-Realistic Virtual Avatar

f:id:s44511173:20191013194538p:plain

ヘッドセットのカメラで顔を認識し、アバターの表情をリアルに合わせるといった機能です。アバター自体は事前に作る必要があります。

Oculus for Business

f:id:s44511173:20191013195020p:plain

ビジネス向けのVRに特化したヘッドセットです。
実際にヒルトンホテルや外科手術の訓練現場で使用され、未使用よりも成果が上がったとのこと。
なにより、今までVRはゲーム向けとしてしか認識されていなかったのが、ようやくビジネス向けにも認められてきたというのが素晴らしい!!
Oculus Connectでも「THE TIME IS NOW(VRビジネスの時はきた)」がロゴになっていたようです。

ARトレンド

SparkAR

f:id:s44511173:20191013195811p:plain

FacebookInstagramで利用できるAR機能。
カメラアプリで撮影した写真を使っていたので、そんな機能がついてること知らなかったとですよ・・・。

LiveMaps

f:id:s44511173:20191013200157p:plain

ARグラスになるのか、はたまたコンタクトレンズになるのか。
形態は不明ですが、これが実現したらマジでSF映画の世界になります。
例えば映画館に行くと、映画の情報が空間に浮かんで表示されたり
竹林に行けばバーチャルな鶴が現れたり。
同じ時間・同じ場所にいる人たちが全員同じ映像を見れるようになるとのことで、実現できたら末恐ろしいとまで思いました。

f:id:s44511173:20191013200454p:plain

でも、この機能欲しいw
階段を降りるときにリマインダーが表示される機能ww
階段降りちゃってから忘れ物に気づいた時の絶望感www

VR会議

f:id:s44511173:20191013200641p:plain

私自身はVR会議どころか、TV会議もSkype会議もしたことがないのですが。
やはり表情や目線、手の動きが見える会議が一番とのことでした。

Skype会議だと話がかぶってしまい、結局はトランシーバーのような会話になってしまう。TV会議だと映らない人もいる。
文字だけでは伝わらないニュアンスが必要ではあるが、かといって会議のために全員が対面するだけの移動費・時間・場所の準備はもったいない。そういった経緯から開発に至ったとのことでした。

実際にVR会議をしながらVR会議ソフトを開発され、実体験をもとに改良されていったようです。

結論

Oculus LinkとハンドトラッキングtoB VRトレンドが熱い!!!(当社比)

 

 

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】【OculusQuest】制限時間を表示する

f:id:s44511173:20191009165429g:plain

制限時間のカウントダウンを、イライラ棒の先端に表示してみました。
数字表示と共に時間ゲージの円が欠けていく仕組みになっています。

開発環境

イライラ棒Canvasを追加する

f:id:s44511173:20191009170442p:plain

Render ModeはWorld Spaceに設定しましょう。
Event CameraにはOVRCameraRig > TrackingSpace > CenterEyeAnchorを設定します。

カウントダウン用のTextをCanvasに追加する

アウトラインをつけたかったのでTextMeshProにしましたが、普通のTextでもOKです。

時間ゲージ用のImageをCanvasに追加する

f:id:s44511173:20191009171415p:plain

時間ゲージ用の画像を準備します。
インスペクタでTexture TypeをSpriteに設定しておきましょう。
これをImageのSourceに設定します。

 

f:id:s44511173:20191009171856p:plain

そうすると、Imageのインスペクタ上にImage Typeという項目が出てきます。
こいつをFilledに、Fill MethodをRadial360に設定してやります。
これで円が欠けていく時間ゲージが実現できます!
上から欠けていきたいのでFill OriginをTopに、満円からスタートしたいのでFill Amountは1にしましょう。

スクリプトからゲージ値を設定する

あとはこんな感じのスクリプトを書けばOK!

[SerializeField]
private TextMeshProUGUI time; //インスペクタからセット
[SerializeField]
private Image timebar; //インスペクタからセット
private int timelimit = 30; //ステージ毎に値を変える
private bool run = true; //ゲームオーバーになったらfalse

public async void Countdown() {
    while (timelimit > 0) {
        await Task.Delay(1000);
        timelimit--;
        if (run) {
            time.text = string.Format("TIME:{0:00}", timelimit);
            timebar.fillAmount -= timediff; //時間ゲージの満ち欠けを設定
        }
    }

    if(timelimit == 0) {
        run = false;
        GameOver();
    }
}

 これでイライラ棒の先端に制限時間を表示できるようになりました!

 

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

 

【Unity】【OculusQuest】Bloomさせる

f:id:s44511173:20191008113317p:plain

BEAT SABERっぽい雰囲気を目指すんなら、やっぱりBloomさせなきゃですよね!?

開発環境

エフェクト使用について

unity3d.com

上記URLの「VR でのイメージエフェクトの使用」に記載されていますが、イメージエフェクトは非常に負荷が高くVR向けではありません。
よって、使用の有無をよく検討する必要があります。

VRイライラ棒に関して言えば、他に重たい処理もありませんし
何よりBEAT SABERっぽくするのが大目的です。
よって遠慮なく使うことといたしました。

Post Processingをインストールする

f:id:s44511173:20191008114748p:plain

Bloomさせる一番手っ取り早い方法は、PackageManagerにあるPost Processingを使うことだと思います。Post ProcessingはメニューのWindow > Package Managerから表示されるPackageウィンドウからインストールします。
※未インストール時は、上記画面のボタンがInstallになります。

Post Process Layerをアタッチする

エフェクトを適応するカメラにPost Process Layerコンポーネントをアタッチします。
OculusIntegrationを使用している場合、OVRCameraRig > TrackingSpace > CenterEyeAnchor にアタッチしましょう。

f:id:s44511173:20191008115508p:plain

アタッチしたら、エフェクトを適応するLayerの設定を行います。
Anti-aliasingのModeですが、せっかく準備されているのです。遠慮なく使っちゃいましょうw

アンチエイリアスについてはProject SettingsのQualityで2x~4x Multi Samplingを適応するようにOculusで推奨されていますが、Post Processで適応するので今回は外してみました。

HDRを適応する

f:id:s44511173:20191008121848p:plain

Post Processingを使用するにはHDR(High Dynamic Rangeレンダリング)を有効にする必要があります。
VRではカメラの設定からHDRを有効にはできないので、Project SettingsのGraphics Settingsから設定します。

f:id:s44511173:20191008122314p:plain

Use Defaultsをオフにすると各項目が活性になりますので、Use HDRをONにします。
Low・Middle・Highの設定項目がありますので、同様にすべて設定します。

Post Process Volumeオブジェクトを作成する

新規オブジェクトを作成し、レイヤーをPost Process Layerで設定したのと同じものを設定します。そのオブジェクトにPosr Process Volumeスクリプトををアタッチしましょう。

f:id:s44511173:20191008123053p:plain

Is GlobalはONにしておきます。OFFにすると、オブジェクトからの距離でエフェクトをかける範囲を設定できます。
ProfileでNewボタンを押下すると、プロファイルが作成されます。
このプロファイルにエフェクトを追加していく感じになります。

Bloomを追加する

PostProcessStack Profileを開くと、エフェクトを追加する画面が出てきます。
こちらからBloomを追加しましょう。

f:id:s44511173:20191008123424p:plain

IntensityはBloomの強さ、Thresholdは発光の閾値です。
オブジェクトのIntensityが設定値以上のオブジェクトのみが発光します。
VRですので、Fast ModeはぜひONにしておきましょう。

これでBloomの設定は完了です!

発光マテリアルの作成

マテリアルを発光させるには、Standard ShaderのEmissionを使用します。
Emissionについては、下記URLに詳しく記載されています。

docs.unity3d.com

 

VRイライラ棒ではイライラ棒とステージが発光しています。
発光の度合いを変えるために、イライラ棒側のIntensityを強めに設定してあります。

f:id:s44511173:20191008124401p:plain

左がイライラ棒、右がステージのIntensity設定です。

 

f:id:s44511173:20191008125751g:plain

これで発光強度の異なるオブジェクトが配置できました!

結論

  1. Bloomさせるには、Post Processingを使用する
  2. オブジェクトを発光させるには、Standard ShaderのEmissionを設定する
  3. EmissionのIntensityの強さによって、発光強度を変えられる
  4. 発光させたくないオブジェクトは、Intensityを閾値以下に設定する
  5. Bloomすると一気にBEAT SABERっぽくなる!(当社比)

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】【OculusQuest】立ってプレイするゲームを作る

OculusQuestはスタンドアロンVR機です。
せっかくなんですから、立ってプレイしたいですよね!?
そんなあなたの希望を叶える方法をご紹介します。

開発環境

OVRPlayerControllerを使う

atelier-hinata.hatenablog.com

↑の記事でご紹介しましたが、OVRPlayerControllerを使うとVR空間内を自由に移動することができます。
このコンポーネントUse Profile Dataというパラメータがありまして、プレイヤーの物理的な身長データを使用するかどうかを選択できます。
まずはこいつをONにしましょう。

f:id:s44511173:20191007145127p:plain

TrackingOriginをFloor Levelにする

次に、OVRCameraRigにアタッチされているOVRManagerのTracking Origin Typeを変更しましょう。

f:id:s44511173:20191007144854p:plain


これでオッケーです!
あとはプレイ前のガーディアン設定で、床の調整をしっかりとやっておきましょう。
コントローラを床にタッチさせることで、正確に検知することができます。

比較してみる

f:id:s44511173:20191007150921g:plain

f:id:s44511173:20191007150941g:plain

あああ、めっちゃ分かりづらい(汗

1個目の動画がUseProfileData=あり、TrackingOriginType=FloorLevel
2個目の動画がUseProfileData=なし、TrackingOriginType=EyeLevel

1mのキューブを床に配置しています。
なんとなく違いがお分かりいただけたでしょうか・・・。

結論

  1. 立ってプレイするアプリを作るには、OVRPlayerControllerのUseProfileData=あり、OVRCameraRigのTrackingOriginType=FloorLevelに設定する。
  2. OculusQuestに床位置をきちんと認識させるには、ガーディアン設定時にコントローラで床をタッチすると良い。
  3. ぶっちゃけ、設定はそのままでカメラの位置だけ上の方に設定するのでも良かったりするのかも・・・?(未検証)

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】【OculusQuest】イライラ棒を作る

f:id:s44511173:20191001175736g:plain f:id:s44511173:20191001175741g:plain

イライラ棒を作った時の苦労話をツラツラと書いていきたいと思います。
結構苦労したんですよ、本当に。

開発環境

OVRPlayerControllerを使う

Oculus Integrationをインポートすると、膨大な量のサンプルシーンやPrefabがインストールされます。今回はその中から、OVRPlayerControllerを使用しました。
Assets > Occulus > VR > Prefabs に入っています。

OVRPlayerControllerにはCharacterControllerがアタッチされているので、スクリプトを組むことなくVR空間内を自由に移動することができます。
これにはOVRCamerRigがアタッチされていますので、通常のCameraがシーン内にある場合は削除しましょう。

AvatarGrabberRightを使う

今回は右手でイライラ棒を操作するので、AvatarGrabberRightを使用します。
Assets > Occulus > SampleFramework > Core > AvatarGrab > Prefabs に入っています。

なぜこれを使ったかというと、最初は手のアバターを表示してイライラ棒を掴んで操作しようと思っていたからです。
ですがBEAT SABERを思い出してみたら、手のアバターは表示されていないんですよね。という訳で、その名残というのが理由ですw

コントローラの位置や角度が取得できれば、他でも良いと思います。

 

f:id:s44511173:20191004144012p:plain

なお、AvaterGrabberRightはOVRameraRigの子オブジェクトとして設定します。
OVRPlayerControllerでUser Profile Dataを使用する設定にしていると、こうしないと手の位置が正しく表示されませんでした。

イライラ棒を作る

f:id:s44511173:20191004144249p:plain

柄の部分を中心位置としたいので、柄(Cube)の子オブジェクトとして刃(Cylinder)をくっつけました。

 

f:id:s44511173:20191004144623p:plain

イライラ棒を引っこ抜けないように(引っこ抜いたらビリビリさせる)、刃の前後にもコライダをくっつけました。
最初は透明にしていたのですが、透明だとビリビリしたときに「なんで!?」となってしまったので、すこーしだけ見えるようにしてみました。
が、なんだか余計に見えづらくなってしまったという・・・(汗)

動かしてみる

f:id:s44511173:20191004145439g:plain

これでイライラ棒が出来上がりました!
なお、イライラ棒ですので失敗すると当然のごとくビリビリしますw

f:id:s44511173:20191004150049g:plain

OVRInput.SetControllerVibrationメソッドを使用すると、コントローラをビリビリさせることができます。

ビリビリのエフェクトは、勉強中のUnityゲームエフェクト入門で作ったやつをそのまま使ってしまいましたw

www.shoeisha.co.jp

 

結論

  1. OVRPlayerControllerを使うと、VR空間内を自由に移動できる
  2. AvatarGrabberRightを使うと、コントローラの位置を取得できる
  3. コントローラをビリビリさせるには、OVRInput.SetControllerVibrationメソッドを使う
  4. イライラ棒すっぽ抜け防止のアイディアが最悪。もっと良い案モトム。

 

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

 

 

【Unity】【Aseet】Exploderを使ってみた

メッシュを爆発させるアセットで有名なExploderを買ってしまいました。
Humble Unity Bundle祭りで、お財布のヒモが緩んだ隙の出来事でした。

 

f:id:s44511173:20191003122825g:plain

f:id:s44511173:20191003123013g:plain


VRイライラ棒の記事を次回から・・・と言っておきながら
まさかのアセットネタです。だって書きたかったんだもん。
しかも紹介するのが、Bundleの中身じゃないという。ナニコレ珍百景

 

Exploderとは

assetstore.unity.com

explodeとは爆発させるという意味でして。
その名の通り、メッシュを爆発させてくれるアセット(35ドル)になります。
めっちゃ楽しい。いろんなものを爆発させたくなります。危険思想ですな。

使い方

まず、Exploderを購入&ダウンロード&インポートします。
消費税はキッチリ10%取られました。9月のうちに買っておくんだった・・・。

 

f:id:s44511173:20191003124617p:plain

次に、ヒエラルキー上にExploderのPrefabを配置します。
Assets>Exploder>Prefabsに入っています。

 

f:id:s44511173:20191003125846p:plain

破壊したいオブジェクト(青)と破壊したくないオブジェクト(赤)を並べます。
スフィアと衝突したら破壊する仕組みです。
破壊したオブジェクトには「Exploder」タグをセットします。
これはアセットをインポートすると自動で追加されます。
こんなコードを書いて、スフィアにアタッチします。

[SerializeField]
private ExploderObject exploder; //インスペクタからセットしておく
private Rigidbody rigid; //キーボード操作用
private readonly string ExplodalTag = "Exploder"; //爆発させたいオブジェクトのタグ
private readonly string UseObjectTag = "UseObject";// 爆発させたくないオブジェクトのタグ

void Start()
{
    rigid = GetComponent<Rigidbody>();
}

void Update()
{
  //WASDキーで操作
    var x = Input.GetAxis("Horizontal");
    var z = Input.GetAxis("Vertical");

    rigid.AddForce(x*2, 0, z*2);
}

private void OnCollisionEnter(Collision collision) {
    if (collision.gameObject.tag == ExplodalTag) {
        // ぶつかった対象を爆発させる
        exploder.ExplodeObject(collision.gameObject);
        Debug.Log(collision.gameObject.name);
    }
    // 移動停止
    rigid.velocity = Vector3.zero;
}

これで動かした結果がこちら。

f:id:s44511173:20191003131640g:plain

・・・なんか、へん。

1回目の爆発は余韻が、破片の飛び散りがあっという間に終わってしまい
2回目の爆発はぶつかってからのタイムラグがありすぎる。
ナニコレ珍百景、アゲイン。

原因を探ってみる

OnCollisionEnterで出力しているデバッグログを見てみると、こんな感じになっていました。

f:id:s44511173:20191003133023p:plain

おふ。なにこのfragment_xxってヤツら。こんなの 配置してないんだけど!?
ナニコレ珍百景、リターンズ。

おそらくExploderが破壊したメッシュたちの破片にぶつかっていて
そいつらをも破壊しようとしているんだと思われます。なんて律儀な。

設定値を確認してみる

それって、まず最初にやることなんじゃないの・・・?

f:id:s44511173:20191003133538p:plain

まずは爆発関連から。

  • Radius・・・爆発判定の半径。後ほど記述しますが、オブジェクトを爆発させることの他に、自身を爆破して周囲を巻き込むことができます。その巻き込む半径になります。
  • Force・・・爆発力
  • Target Fragments・・・爆発させた後の破片の数。初期値が100になっていまして、これだとめっちゃ重たくなるw
  • Use Force Vector・・・爆破した破片の飛び散る方向をセット(ONにすると、XYZ入力ボックスが出てくる)
  • Ignore Tag・・・爆破したいオブジェクトの判定に、タグを使いたくないときにONにします。その場合、爆破したいオブジェクトにはExplodableスクリプトをアタッチする必要があります。
  • Explode Self・・・爆破させた後、自身を非アクティブにします。
  • Hide Self・・・爆破させた後、自身を非表示にします。
  • Delete Original Object・・・爆破したオブジェクトをdeleteします。オフの場合は、非アクティブになります。
  • Uniform Distribution・・・デフォルトでは、Exploderの中心から近い位置にあるオブジェクトは、多くの破片になります。遠いオブジェクトは、少ない破片になります。このオプションをオンにすると、オブジェクトの中心からの距離に関係なく、オブジェクトごとに均等にフラグメントの数が作成されます。
  • Split Mesh Islands・・・同じメッシュの非接続部分を分離して破片にします。
  • Disable Triangulation・・・???
  • Use 2D Physics・・・2Dに適応する際、ONにします。
  • Use Cube Radius・・・爆破範囲をスフィアではなく、キューブに設定します。
  • Multi-Threading・・・使用するスレッド数を設定します(最大3)
  • Cutting Plane Angle・・・破片の形状を選択します。

f:id:s44511173:20191003140247p:plain

次に、破片関連。

  • Pool Size・・・破片オブジェクトはプールされているのですが、その上限数を設定します。TargetFragmentより大きくしないと、例外が発生します。
  • Explodable Fragment・・・破片を爆破対象とするかどうか、です。これをオフっておけば、爆破した破片にあたって爆破して、さらにその破片を爆破して・・・っていう永久ループを免れます!!
  • Layer・・・破片オブジェクトのレイヤーを設定します。
  • Mesh Colliders・・・破片のコライダをメッシュコライダにします。重たいので、非推奨とのこと。
  • Disable Colliders・・・オンにすると、破片にコライダが適応されません。
  • Max Velocity・・・破片の最大速度を設定します。
  • Max Angular Velocity・・・破片の最大角速度を設定します。
  • Inherit Parent Physics・・・親オブジェクトの物理プロパティを継承します。
  • Mass・・・破片の重量を設定します。
  • Use Gravity・・・オンにすると、重力がかかります。
  • Angular Velocity・・・破片オブジェクトの角速度を設定します。MaxAngularVecocityで設定した以上にはならないっぽい。(設定自体はできます)
  • Random Angular Velocity・・・角速度をランダムにします。オフの場合、自身でセットした値にすべてのオブジェクトが回転します。
  • Freeze Position・・・オンにすると、面白いことになりますw
  • Freeze Rotation・・・回転しない軸を設定します。
  • Material・・・破片のマテリアルを設定します。設定しない場合は、爆破されたオブジェクトのマテリアルが適応されます。
  • Fragment Deactivation・・・破片の無効化を設定します。Never/Outside Of Camera/Timeoutから選択します。
  • Fragment Particles・・・破片にパーティクルを付けることができます。

以上を踏まえて

やりたいことを整理しましょう。

  1. スフィアに青いキューブがぶつかったら、その青キューブのみを爆破。
  2. スフィアに赤いキューブがぶつかったら、赤いキューブの半径2m範囲で爆破。
  3. 破片は爆破対象ではない。したがって、スフィアがぶつかっても爆発しない。
  4. 破片は床に散らばる。3秒後にフェードアウト。

設定値はコチラ!

f:id:s44511173:20191003150201p:plain

f:id:s44511173:20191003150007p:plain

 

コードは、OnCollisionEnterをこんな感じにしてみました。

private void OnCollisionEnter(Collision collision) {
    if(collision.gameObject.tag == ExplodalTag) {
        // ぶつかった対象を爆発させる
        exploder.ExplodeObject(collision.gameObject);
    } else if(collision.gameObject.tag == UseObjectTag) {
        // 自身が爆発して、周囲を巻き込む
        exploder.ExplodeRadius();
    }
    // 移動停止
    rigid.velocity = Vector3.zero;
}

直接オブジェクトを爆破したい時はExplodeObjectを、周囲を巻き込みたい時はExplodeRadiusを使います。
巻き込まれて爆破したいオブジェクトには、タグにExploderを設定しておきましょう。

実行結果

f:id:s44511173:20191003150325g:plain

やりたかったことが、できました!!

結論

  1. 爆発させたい時は、Exploderアセットを使うと便利
  2. 初期値のままだと、思うように動いてくれないので注意
  3. 面倒臭がらず、まずは取説を読もう
  4. これでVRイライラ棒で失敗した時に・・・クククッ

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】【OculusQuest】急にUnityがOculusを認識しなくなった

f:id:s44511173:20191002172455p:plain

いつも通りにUnityでBuild and Runを実行したら、こんな画面が出てきた。。
なんで?どうして?
Oculus QuestはPCに接続されているのに・・・。

現象

Unityでapkをビルドする際、毎回上図のようなエラーが出るようになってしまいました。昨日までは、問題なくビルドできていたにも関わらず、です。

PCのエクスプローラからは、Oculusが見えていました。
ですが、OculusをPCとつなぎ直すたびに、Oculus側で「このデバイスとの接続を許可しますか?」のメッセージが出るようになってしまいました。

原因

なぜだか、OculusQuestの開発者モードが、勝手にOFFになっていたことが原因でした。チョ、マテヨ。なに勝手にオフってくれてんだよ!!

 

f:id:s44511173:20191002173121j:plain


開発者モード設定は、モバイルにインストールしているOculusソフトの
設定>Oculus>その他の設定>開発者モード
から確認できます。

結論

  1. 急にUnityがOculusを認識しなくなったら、Oculus側の開発者モードを疑おう
  2. 勝手に開発者モードがオフられた原因は不明。(わかり次第、更新します)

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】【OculusQuest】VRイライラ棒作ってみた

 f:id:s44511173:20191001175736g:plain

 

f:id:s44511173:20191001175741g:plain
OculusQuest、めちゃめちゃ楽しいです。
けど、結構しんどいです。あちこちでドハマリします。
今回はポートフォリオ用に、VRイライラ棒を作ってみました。
なんとなくBEAT SABER的な雰囲気で。え、似てない?光ってるだけやん?
いいんだよ、雰囲気だから。

ということで、イライラ棒が出来上がるまでにドハマリした部分を
(というかほぼ全部)
ご紹介してきたいと思います。詳しいことは、次回から。

ざっと、記事にする内容をラインナップしてみます。

  • イライラ棒をコントローラ表示代わりとする
  • 立ってプレイする
  • Bloomさせる
  • 視点に合わせてテキストを表示する
  • カウントダウン表示する
  • 紙吹雪を散らす
  • 壁を天井側から倒す

他にも思いついたら、書いていきます!

 

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】子オブジェクトの衝突を親オブジェクトで検知する

Oculus QuestでのVRアプリ制作にハマッています。いろんな意味で。
本日は衝突判定について、新たに知ることができたネタをご紹介します。
基本中の基本かも知れないけど。Oculus関係ないけど。

Oculus IntegrationのOVRGrabber

Oculus Integrationでは、手のアバターで物体をつかめるようにする機能が用意されています。それが掲題のOVRGrabberです。
これを手のオブジェクトにアタッチするわけなのですが、詳細な使い方はまた今度ご紹介するとして。

f:id:s44511173:20190912125900p:plain

このスクリプトをアタッチしたオブジェクトには、ご覧の通りColliderはアタッチされていません。Rigidbodyはありますけど。
では、コードを見てみましょう。

コード内では、OnTriggerEnterとOnTriggerExitが実装されています。
あれれ、Colliderを持っていないのにどうしてコールされるんだ??

親オブジェクトがRigidbodyを持つ場合、子オブジェクトの衝突も検知できる

ということらしい。
ためしにColliderなしのCubeを2個配置します。
それぞれに子オブジェクトを作成し、そちらにBoxColliderをアタッチして実験してみました。

f:id:s44511173:20190912131840g:plain

親にRigidbodyなし版。衝突してない感じ。

f:id:s44511173:20190912131835g:plain

親にRigidbodyあり版。衝突しています!!

結論

  1. 親オブジェクトにRigidbodyを付けることで、子オブジェクトの衝突を検知できる
  2. Oculusハマる。いろんな意味で。

 

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

 

【Unity】【Oculus】HMDを外したらポーズ状態にする

Oqulus Questでビートセイバーやっていたら、腕が筋肉痛になりました。
できれば上腕二頭筋ではなく、上腕三頭筋に効いてほしい。

開発環境

  • Unity 2019.1.2f1
  • Oculus Integration 1.39
  • Oculus Quest

HMDを外すとポーズになるゲームがある

ビートセイバー等のゲームは、HMDを外すとポーズ状態になりますよね。
その後15秒ほどすると、Oculus本体がスリープになります。
スリープはOculus自体の設定ですが、ゲームのポーズはゲーム側で設定するようです。

HMDの装着状態を取得する

Oculus IntegrationにはOVRManagerというクラスが用意されています。
こちらのisUserPresentというプロパティから、HMDの装着状態を取得することができます。

developer.oculus.com

↑相変わらず素っ気ない埋め込みリンクですがw
OVRManagerのリファレンスです。英語です。しんどいです。

 

private bool isPose = true; // ポーズ状態
void Update()
{
    if (!OVRManager.instance.isUserPresent) {
        if (!isPose) {
            // ポーズ処理を実装
            isPose = true;
        }
    } else {
        if (isPose) {
            // ポーズ解除処理を実装
            isPose = false;
        }
    }
}

こんな感じのコードを書いてやればOKです。

結論

  1. HMDを外した時にゲームをポーズ状態にするのは、スクリプトで実装する必要がある
  2. OVRManagerには、HMDの装着状態を取得できるプロパティが用意されている

なお、現在のOculus Integrationの最新Verは1.40の模様です。
アップデートしたいけど、なんか動かなくなりそうで怖くてできない(><)

 

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】Mesh ColliderのConvexオプションについて

fbxをインポートすると、メッシュ情報からMesh Colliderが作られますよね。
そのMesh Collider同士の衝突判定について、めっちゃハマったお話です。

メッシュ同士の衝突について

Unityマニュアルに、以下のように記載されています。

docs.unity3d.com

上の記事には、Convex がオンとなっているメッシュコライダーは、他のメッシュコライダーと衝突することができます。と書かれてあります。
さっそく、試してみることにしました。

衝突したい両方のConvexをオンにしてみた

これが、思った通りに衝突判定してくれない。
正確に言えば、衝突していないのに起動時に衝突検知し、そのあとは衝突させても検知してくれない。
これで、かなり悩みました。

Convexをオンにすると、メッシュ通りのコライダにならない

ということが判明!!!
下のキャプチャを見てみてください。
VRイライラ棒を作っていますw

f:id:s44511173:20190904162547p:plain

こちらがConvexオフ。

f:id:s44511173:20190904162552p:plain

こちらがConvexオン。緑のラインがコライダの形を表しています。
なんと、メッシュの外枠を囲った形になっているではありませんか!!

これのせいで、突き刺さっている棒のコライダが起動時に衝突検知してしまい、そのあとは衝突中判定になっていたのですね。ナンテコッタイ。
コライダの形を簡易化しているってことなのかな。

コライダの形を変えたくない場合はConvexをオフにする

ではどうすれば良いかというと、コライダの形をメッシュ通りにしたいオブジェクトについては、Convexをオフすれば良いようです。
今回は衝突したときに、イライラ棒に電流を流したい(バイブレーションさせる)ので、イライラ棒だけConvexをONにしました。
コライダの形も、まあなんとか。

f:id:s44511173:20190904163334p:plain

前後の四角いコライダは、イライラ棒すっぽ抜け検知用です。

コライダの形を変えたくないけどMesh Collider同士を衝突させたい

そんな無茶な要望に応えてくれるアセットもあるようです。しかも無料!!

kan-kikuchi.hatenablog.com

こちらのサイト様で紹介されていました。
もっと早く気づけばよかった・・・!!
Mesh Colliderを作るのではなく、他のColliderを組み合わせてメッシュと同じ形状を再現してくれるそうです。スバラシイ!!

結論

  1. メッシュに合わせてコライダを作ってくれる。それがMesh Collider。
  2. Mesh Collider同士の衝突判定では、Convexをオンにしよう。
  3. Convexをオンにすると、メッシュ通りのコライダにならないので注意。
  4. アセットもあるよ!

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

 

【VR】【Unity】Oculus Questで手が動かせない

せっかくOculus Quest用アプリがビルドできるようになったのに
手のアバターが、なぜだか動いてくれないの。。。

Oculus Integrationのバージョン

2019/08/27現在で最新の1.39を使用しています。
いろんなサイト様で、何もせずとも手のアバターが動作していることから
古いバージョンだと問題ないのかもしれません。

対応方法

qiita.com

こちらのサイト様を参考にさせていただきました。
公式にも手順が書かれております。
Oculusの公式ページを埋め込みリンクにすると、めっちゃ素っ気ないw

developer.oculus.com

  1. まず最初に、シーンに配置したOVR CameraRigのインスペクタで、OVR Manager>Target DevicesのElementをQuestにします。
  2. 次に、Oculusメニュー>Tools>Remove AndroidManifest.xmlを選択します。
  3. さらに、Oculusメニュー>Tools>Create store-compatible AndroidManifest.xmlを選択します。順番は守ってね!
  4. すると、 Assets/Plugins/Androidフォルダの下に、AndroidManifest.xmlが生成されています。これには、以下が記述されているはずです。
    <uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
  5. AndroidManifest.xmlの<intent-filter>タグ内に、以下を追加します。
    <category android:name="android.intent.category.LAUNCHER"/>

これで、ようやっと手が表示されるようになりました!
長かったよぉぉ。

結論

  1. Oculus Integrationがバージョンアップしたら、動きが(結構)変わる(かも知れない)ことを覚悟しておこう。
  2. 探せば、先駆者様が絶対にいる!めげずにググろう!(今回、かなり泣きそうになったw)

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【VR】【Unity】Oculus Questアプリをビルドする

つつつ、ついに買っちゃいました!
Oculus Quest!!!
PSVRを持っているので、Oculusを買うことは無いかなと思っていたのですが
開発に使うってことで(言い訳?)。

ということで今回は、UnityでOculus Quest用にビルドする方法を備忘録として載せておきます。

Unityのバージョンを確認する

これ、めっちゃ大事。
ぶっちゃけ自分、これのせいで半日無駄にしました(涙)

developer.oculus.com

上記ページに書かれているのですが、推奨されているUnityのバージョンは以下となっております。

  • 2017.4 LTS
  • 2018.4 LTS
  • 2019.1.2f1

そう、私はちょうどこの時、Unityのバージョンをアップグレードしたばかりだったのです!!(2019.2.0f1)
これのせいで、ビルドが失敗していたものと思われます。
なお、2019.1.2でビルドしたら成功するようになりました。

Oculus Integrationをインポートする

assetstore.unity.com

お次に、任意のUnityプロジェクト を作成して、Oculus Integrationをインポートします。そうすると、諸々必要なコンポーネントと共に、たくさんのサンプルシーンもインポートされます。今回はその中から、Assets>Oculus>AampleFramework>Usage>DistanceGrabを開きます。

Unityプロジェクトの設定を変更する

あとはおなじみ、Android向けの設定をプロジェクトに施します。

  1. Build Settings>platformでAndroidを選択し、Switch Platformボタンを押す
  2. Player Settings>Company NameとProduct Nameを任意のものに変更します。
  3. Player Settings>XR SettingsのVirtual Reality Supportedにチェックを入れ、Virtual Reality SDKsの+ボタンからOculusを選択します。
  4. Player Settings>Other Settings>Identification>Minimum API Levelを19~にする。
  5. ヒエラルキビュー上のOVRPlayerController>OVR CameraRigのインスペクタで、OVR Manager>Target DevicesのElement 0をQuestに変更する。
  6. Player Settings>Other Settings>Identification>Package Nameを設定する。
  7. Player Settings>Other Settings>Rendering>Graphics APIsからVulkanを削除する。これを削除しないと、ビルド時にエラーとなります。

Oculus Questを開発者モードに変更する

Oculus Questを接続したOculusアプリの設定からその他の設定>開発者モードを開き、開発者モードをONにします。その際、団体登録を促されますので、登録しましょう。

次に、Oculus QuestをPC(Windows10)に接続します。Oculus側に接続受け入れ許可を聞くダイアログが表示されますので、許可します。

うまく進まないな?と思ったら、Oculus Questを再起動してみます。私もどこかのタイミングで再起動しました(詳細失念・・・)。

ビルドしてOculus Questにapkをインストールする

Build And Runでも、ビルド後にadb installコマンドでもOKです。前者の場合、自動的に実行されています。後者の場合、Oculusのライブラリ>提供者不明のアプリ内から起動します。

結論

  1. Windows10!Unityは2017.4/2018.4/2019.1.2!これ大事!!(実はWindowsでもハマっていたのは内緒だ)
  2. Oculusの提供しているアセットがあるので、それを使う
  3. Oculus Questを開発者モードにする
  4. HMDをかぶる時は、机の上を片付けよう。特に飲み物類!

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【C#】NULL条件演算子について

し、し、知らなかった。

C#6.0以降、null条件演算子なるものがあったってことを・・・。

事の発端

github内のソースを見ていて、ふと目にとまったコードがありました。

  var str = val?.ToString();

こんな風に書かれている箇所がありまして。
これ、なんぞや?と思ってググってみたのです。

まぁ見た感じ、nullチェックなんじゃなかろーかと思って「C# nullチェック」と
検索窓に入れてみたのですよ。
そしたら、

f:id:s44511173:20190809151749p:plain

こーんなステキな検索候補が出てくるじゃありませんか!

NULL条件演算子

さっそく「C# nullチェック 演算子」でググッた結果の一番上の記事(安直w)をオープン!そこは私のバイブル「@IT」の記事でした。

www.atmarkit.co.jp

よーするに、オブジェクトのメソッドやフィールドにアクセスする際のnullチェックを、「オブジェクト名+?」で簡略化できるよってことらしいです。

今までの書き方@自分

自分、不器用なんで。
今まで、こんな風に書いてました。

  var str = val != null ? val.ToString() : null;

これでも間違いではないのです、古い書き方だけど。(三項演算子というらしい)
若かりしころ、こんなコードを書いちゃう自分カッコ良くね?
なんてコッパズカシイことを思っていたものです。
ほんとに若かりしころの話ね。ほんとにほんとね。

ところが@IT様の記事によると、これはスレッドセーフではないと。
val!=nullでnullチェックをした時にはOKだったかもしれないが、ToString()する時点でnullになっているかも知れないと。
そりゃそうだ。むしろとっとと気づけ自分。

それと比較して、null条件演算子はスレッドセーフであるため安全ですし、コードがかなり簡略化できるので非常に使い勝手が良いです。

結論

  • C#6.0以降、null条件演算子なるものが使えるようになった
  • null条件演算子はスレッドセーフ
  • 三項演算子はスレッドセーフではない
  • 常にスレッドセーフを考慮してコーディングしましょう@自分

 

 

↑↑↑ ぜひ遊んでみてください!↑↑↑

【Unity】複数の警告を無視する

インスペクタからオブジェクト等をセットする際、public変数にする方法と、privateで[SerializeField]属性をつける方法があります。
私は後者をよく使うのですが(ボッチ開発だけどpublicは使わないw)、スクリプト内で初期値を設定していないとwarningが出るんですよね。
これを踏まえて、警告を制御する方法をご紹介します。

  • Unityバージョン:2019.3.0a8
  • ランタイム:.NET4.x

[SerializeField]privateするとどうなるか

f:id:s44511173:20190724123036p:plain

上図のような警告がコンソールに表示されます。
出ている警告は、CS0649ですね。これは「値が割り当てられていない、初期化されていないプライベート フィールドまたは内部フィールドの宣言が検出されました。」という警告です。

docs.microsoft.com

スクリプト内で警告を制御する(C#

 これを消す手段の一つとして、スクリプト内で警告を制御する方法があります。
警告が出ているスクリプトファイル内で、次を宣言します。

#pragma warning disable 649

ただし、警告が出ているすべてのスクリプトファイル内で宣言する必要があるため、ちょっとめんどくさいですよね。

csc.rspファイルを作る

便利な方法として、Assets/csc.rspファイルを作成し、以下を記述します。

-nowarn:0649

csc.rspとは、defineをグローバルに定義できるファイルのようです。
つまりここに警告無視を宣言しておけば、すべてのスクリプトで参照されるということになります(多分・・・)。
なお、.NET3.5以下を使用している場合はcsc.rspではなく、msc.rspファイルになるようです。

docs.unity3d.com

 

結論

  • privateな[SerializeField]は、警告が出る
  • 警告を消す方法は、該当ファイルに「pragma・・・」を定義する方法と、Assets/csc.rspに「-nowarn・・・」を定義する方法とがある
  • .NET3.5以下の場合、msc.rspを使用する

 

atelier-hinata.hatenablog.com