VR、ゲーム制作、プログラミング。Unity とか Oculus Rift とか。

2015年12月20日日曜日

オキュラスARクッキング「女の子にケーキを作ってもらう方法」

この記事は Oculus Rift Advent Calendar 2015 の 20 日目です。

9 日目は shikemokumk 氏の VR時代のノベルゲーム開発 でした。

はじめに

未遂です。ごく近日中に続きを書きます…。

完遂しました!(2015/12/24)

クリスマスも近いことですし、女の子にケーキを作ってもらおうと思います。



材料



イチゴや生クリームは高いので、安い材料と最先端の技術でコストを抑えてもらいます。
そもそも女の子がいない問題も解決できる完璧なレシピです。

  • 小麦粉 … たくさん
  • 砂糖  … そこそこ
  • 卵 … 1 つ
  • 牛乳 … 少し
  • バター … いい感じに
  • ベーキングパウダー … 適量
  • Oculus Rift DK2 … 1 台
  • Ovrvision Pro … 1 台
  • Unity … 5.2.2p2
  • Oculus Runtime … 0.8.0.0
  • Oculus Utilities … 0.1.3.0
  • アセット … 少々

作り方


材料を混ぜ合わせて生地を作ります。




クッキングシートで型紙を作ります。
は?マーカーレストラッキング?この懐かしい味わいの良さがわからんのかね??



フライパンに型紙を敷き、生地を流し込んで焼きます。



焼き上がりました!いやダメだこれ…

「明日もう一度この記事に来てください。本当のクリスマスケーキをお見せしますよ」

なにとぞ…。

明日は junyash 氏です。

作り方(続き)

ここから追記です。(2015/12/24)



2 枚目を焼きました。熱や油がフライパンになじんでキレイになりましたが、まだまだですね。



人生、困ったらチョコレートソースを塗れば大体何とかなります。


ここで、あらかじめ用意しておいた OculusRift + Ovrvision Pro の AR コンテンツを取り出します。
イチゴ、生クリーム、女の子はこちらに入っています。

Ovrvision Pro は VR HMD 向けのステレオカメラで、カメラを自分の目にできるデバイスです。

凹み氏の VR 向け高性能ステレオカメラの Ovrvision Pro を手に入れたので詳しく調べてみた - 凹みTips に詳しく書かれていますので、僕が書くことは何もありません!

あ、Ovrvision Pro の動作が不安定なときは電源付きの USB 3.0 ハブに挿すといいかもしれないです。

完成

これで女の子にケーキを作ってもらう準備が整いました!

なお、僕はここまでの料理をすでに女の子 (リアルよめ氏) にやってもらっています。何かのご参考になればと思います。

それでは完成品をどうぞ!


まとめ

あえてマーカーを使うことで、何か出るぞ感が演出できるのは面白いのではないかと思います。

Gear VR やスマホ HMD との相性もよさそうです。

マーカーは焼き目でつけるよりも、白地にココアパウダーのステンシルの方がいいと思います。
背景は真っ白でなくてもよく、マーカーも色がついていてもよいので、抹茶でも可です。

量産するなら焼き印を作るのもよいですね。

VR 推しのカフェさんや、VR イベントのお土産、VR  テーマパークのフードメニューにどうですか!!!(営業)


クレジット

ソフト

動画

調理
  • リアルよめ 氏

ユニティちゃんライセンス
このコンテンツは、『ユニティちゃんライセンス』で提供されています。

2015年12月8日火曜日

[Unity]いつものコードを10秒速く書く、VisualStudioのコードスニペット(配布あり)

この記事は Unity 2 Advent Calendar 2015 の 8 日目です。

7 日目は @kuriharaan 氏の AndroidでビルドはもういいRunしたいってとき でした。

はじめに

\デーン/

public void Update ()
{
    Animator animator = GetComponent<Animator>(); // Update 毎に GetComponent
    if (animator.GetFloat("speed") > 5.0f) { // string 版 GetFloat
        animator.SetBool("isRunning", true); // string 版 SetBool
    }
}

…はい、心がざわつきますよね!実行コストの点でも、書くのが面倒という点でも、理由がなければこんなコードは書きたくないですね。

よく見かけるのは Start でキャッシュするやつでしょうか。

Animator animator;
public void Start ()
{
    animator = GetComponent<Animator>();
}

私は初回アクセスでキャッシュするのが好みですが、

Animator _animator;
public Animator animator
{
    get { return _animator ? _animator : (_animator = GetComponent<Animator>()); }
}

いずれにしても、(Animator に限らず) この手のプロパティはよく書くことになるので、楽に書けるようにしたいと思います。

目次

  • Visual Studio のコードスニペット紹介 (知っている方は読み飛ばしてください)
  • 私が使っているコードスニペットの紹介と配布 (特にプロパティ系)

Visual Studio のこと

Unity 5.2 あたりから Visual Studio Tools for Unity がインストーラーに含まれるようになり、手動で何もしなくても Visual Studio 連携ができるようになりました。

確認していませんが Visual Studio Community 自体も Unity のインストーラでも入れられるようになったとの話もあるようです。

もしこれをお読みの方が MonoDevelop を使っていて、しかし MonoDevelop を愛してまではいないようでしたら、この記事を読むのをやめて Visual Studio をインストールしてみるのに時間を使うのがオススメです。画面を左右に割って 2 つのスクリプトを見比べたり、Ctrl + Shift + M or Q でよく使う Unity の関数を一瞬で入力できますよ!(雑な説明)

コードスニペットとは

こういやつです。


例えば upropc + TAB キー 2 回以下が出るようにできます。

Component _target;
public Component target
{
    get { return _target ? _target : (_target = GetComponent<Component>()); }
}

この Component と target は置換できるようになっているので、さらに TAB を押してから Component を Animator に、target (1 箇所で OK) を animator に書き換えれば終わりです。


詳しく知りたい方は公式の コード スニペット - MSDN - Microsoft をどうぞ。

デフォルトで定義済みのスニペットは Visual C# のコード スニペット - MSDN - Microsoft に載っています。

自分でスニペットを作りたい方は以下が参考になります。残念ながら GUI でスニペットを作成できる公式の Snippetizer は Visual Studio 2013 でしか動きませんでしたが、2013 で作って 2015 に持ってくることはできます。xml ですので、1 つ拾ってきて編集してもよいと思います。

 コードスニペットをVisual Studio拡張機能として広く配布しよう - Build Insider

Unity 用コードスニペット

ダウンロード :


インストール :
  1. Visual Studio を開く
  2. ツール > コードスニペットマネージャー
  3. 言語を C# に変更
  4. My Code Snippet を選択
  5. フォルダパスをコピーしてエクスプローラーで開く
  6. ダウンロードした .snippet ファイルを全てそこにコピー



使い方 :
  1. ソースコード上で upropc 等のショートカットを入力し、TAB キーを 2 回押す (または右クリックからスニペットを挿入)
  2. 置換する箇所を書き換え

簡単な紹介 :

ショートカット主なメソッド等
upropcComponent.GetComponent
upropccComponent.GetComponentInChildren
upropcpComponent.GetComponentInParent
upropcx上記以外用 (Transform.Find 等お好きに)
upropgcObject.FindObjectOfType (シーン全体から)
upropgtGameObject.FindWithTag (シーン全体から)
apropbAnimator.GetBool / SetBool
apropfAnimator.GetFloat / SetFloat
apropiAnimator.GetInteger / SetInteger


9 日目は trapezoid 氏です。

2015年11月24日火曜日

(殴り書き)UnityのVRサポートでパフォーマンスとかプロファイルとか

この記事は絵麻さんを養って幸せな家庭を築く氏の


の Unity VR サポート向けの補足みたいなものです。

環境は Unity 5.2.2p2 + OculusRuntime0.8.0.0 です。
DirectDriverMode が動く人向けです。

VR サポート環境でプロファイラを見ると、CPUの負荷は紫色の Other が、その内訳は OculusWaitForGPU が多くを占めるようになります。

ぱっと見では CPU が 100% 使われているように見えるかもしれませんが、これは CPU での処理が終わって GPU での描画を待っているもので、実際に CPU を使っている時間ではありません。


紫と紫以外が合わせて13.3ms(1sec/75fps)で済んでいるなら問題なし、紫だけで13.3msを越えていたら GPU 負荷高過ぎ、紫以外で13.3msに近い場合は CPU 負荷高過ぎです。

(図を貼りたい。とりあえず上のフォーラムにあるのでそれを見て下さい)

あるフレームについて CPU + GPU で 13.3ms のタイミングで描画できない場合、OculusWaitForGPU は 26.6ms など次のタイミングを待つので、37.5fps になったりします。

あと GPU のプロファイルも環境によっては見られます。GeForceドライバ 358.87 で確認しています。めちゃくちゃ便利です。(プロファイル取るのに追加の負荷がかかりますのでそこは注意)


(出し方は左上の Add Profiler をクリックして選ぶ)

プロファイルを見るときはシーンビューは隠しましょう。当然それを描画するのに負荷が相当かかってます。

あとは CPU 負荷がキツくて GPU に余裕がある場合、PlayerSettings にある GPU Skinning のチェックを入れるのも手です。空いてる GPU のリソースを使うようにお願いできます。物理演算とかでたまに CPU 負荷がハネ上がるフレームがある場合などに有効な気がします。MMD4Mecanim +リアルタイムBulletPhysics するときとか。

とりいそぎここまでです。昼休み終わる

(19:30 ちょっとだけ整理)

2015年6月4日木曜日

[Unity][OculusRift]VRアトラクションにおける振動ユニットの利用とステレオ化について

はじめに

VR コンテンツにおいて、触覚等のフィードバックがあると没入感が上がってより楽しくなったりします。

拙作の VR アトラクションでもこれまで扇風機や噴霧器の制御を行ってきましたが、今回新たに振動ユニットも追加してみました。

上記コンテンツでプレイヤーが乗る飛行機は左右に二基のエンジンがあり、振動ユニットを椅子の座面左右に設置してそれぞれ制御することでイメージと近い体感が再現できるのではないか、と考えたことが動機です。

振動ユニットについて

振動ユニットの先行事例については izm 氏のロボット操縦コンテンツ「めかしむ☆」をはじめ多数あり、 利用にあたっても同氏の記事( VR環境における簡単な振動ユニットの使い方について - izm_11's blog )を参考にさせて頂いております。

振動ユニットは上記記事で紹介されているのと同じで以下のものです。ひとつ 4,000 円くらいと安価で買えます。

【お一人様2点まで】 スピーカーでは再現しきれない重低音の臨場感を振動で再現 50Wハイパワー振動ユニット ボディソニック トランスデューサ ホームシアター 上海問屋 DN-82305 | 【上海問屋】通販サイト

低音域でよく振動するスピーカーで、機器との接続も音声デバイス扱いになります。

20 Hz ~ 100 Hz 程度の可聴域ギリギリの周波数帯でよく振動するのと、そうでない音を入力すると普通に鳴ってしまうので、通常はサブウーファー用出力などローパスフィルタをかけたソースを入力します。

これを椅子の裏面などに、振動がよく伝わるようネジ止めして使います。

VR での利用とステレオ化

さて、こちらの振動ユニットの通常の用途は、既存の映画やゲーム等に接続するだけで低音があるシーンで振動するというものです。

VR コンテンツでも、普通に使う分にはコンテンツ内で低音を鳴らしておけば、あとはスピーカー/ヘッドフォン出力を分岐した先でサブウーファー出力(1 ch)を取り出し、そこに振動ユニットを接続すれば使えます。

これをステレオ化、すなわち椅子の座面の左右に取り付けてそれぞれ別の振動をさせるとなると、課題がいくつか発生します。

基本的な方針としては、左右の振動ユニットをそのまま音声出力の LR に割り当てて、低音の定位(パン)を適用することを考えます。

しかし、通常のヘッドフォン用音声出力は VR HMD に合わせて定位が回転してしまうので、分岐して使うことはできません。

そのため、振動ユニットをヘッドフォン用とは別の音声デバイスとして接続し、プログラム側で鳴らす低音のソースや定位を自前で制御する必要があります。

または、コンテンツの音をヘッドフォンでなくスピーカーから出す場合は VR HMD の回転の影響を受けずに済みますが、単純に分岐してから 2.1ch アンプ等に繋いでサブウーファー出力を取ると 1ch になってしまうので、LR それぞれに個別にローパスをかける必要があります。

(余談ですが、音をスピーカーから出す話は こちら)

今回のコンテンツではヘッドフォンを利用するため、前者の方法になります。低音の定位をすべて自前で計算しないといけないのが手間ですが、今回は飛行機のエンジンの振動に絞って実装して簡略化することにしました。

(手間といっても、各振動源との距離を出して、それに基づいてボリュームとパンを計算するくらいだと思います。遮蔽物の影響など考えだすと厳しくなりますが…)

こちらの構成では別デバイスから低音のみを出力するためローパスは不要ですので、適当なステレオアンプがあればよいです。

しかし、デバイスによってはパンの特性がいまいちで、例えば私のノート PC のステレオミニ出力から、右のチャンネルにのみ音声信号の入った 2ch のデータを再生しても、左からも少し音が鳴ってしまいます。

これでは振動の定位を感じにくいので、USB → ステレオミニ変換できる適当な USB オーディオアダプタ経由などで接続し、同データでちゃんと左が無音(無振動)になることを確認します。

必要な機能

  • スピードに連動して振動の強さを変えたい → ボリューム調整
  • カーブ時は外周側のエンジンを強く、内周側を弱く振動させたい → パン
  • エンジン稼働から徐々に、ゴ、ゴ、ゴ、ゴゴゴ…と周波数を上げていきたい → 周波数コントロール
  • (複数の振動ソースの合成 → ミキシング ※ 今回はエンジンのみのため不要)
いずれも通常の音声処理の枠組みでできそうです。

実装

別デバイスから音を再生する必要がありますが、Unity ではデフォルトの音声デバイス以外使えません。対処方法はいくつか考えられますが、今回は Windows のネイティブプラグインを書きます。

API はお好みでよいですが、ボリューム、パン、周波数のコントロールと複数ソースのミックスのサポートがあるものを選んでおくと手抜きができます。

今回は XAudio2 を使いました。パンはないので左右チャンネルのボリュームで自前実装します。

古いという点を除けば多分 DirectSound がパンもあって楽だと思います。ローレベルの API で波形を自前でいじってもよいです。マルチプラットフォーム対応したいなら OpenAL もよいかもしれません。

さて、ベースとなる波形データはプログラム内部で作成することも可能なのですが、今回はファイルを読み込んでループ再生しておき、そのボリューム、パン、周波数を随時コントロールする方式にしました。

方形波、ノコギリ波などいくつか試しましたが、単純なサイン波がわりとエンジンっぽかったので、20 Hz のサイン波をベース波形として使うことにしました。

ちなみに、波形データの wav ファイルの作成には、単純な波形を合成して効果音を作れる、開発室 Pixel 様のピストンノイズが非常に便利です。

あとは Unity 側で、飛行機の状態に合わせてネイティブプラグイン側に指示を出したり、エンジン音(聞こえる方)を振動と同じように制御してやれば完了です。

なお、ネイティブプラグイン以外の選択肢としては、プロセス間通信(ローカル/ネットワーク)や Arduino を使うなども考えられます。

椅子について

振動ユニットからの振動を座面に十分に伝えるために、木などの固い素材にネジ止めしてやる必要があります。

しかし、移動に車を利用しない身としては椅子を持ち運ぶ運用はきびしいですし、折り畳み椅子でも結構かさばります。

というわけで作ったのがこちら。


これなら現地でお借りした椅子の上に置けばよく、座敷での飲み会でも利用可能。リュックサックに詰めて山も登れます。

アンプの電源もゴツいモバイルバッテリー( 700-BTL017BK )があればギリギリ何とかなりますし、まだコンセントがなくても持ち込みデモが可能…!

演出や体感について

とりあえず飛行機の発進時に「オッ」と言ってもらえたり、体験後に「振動があると違う(良い)」くらいの感想はいただけることが多いです。

一方で、ステレオであることに直接言及されることはほぼありません。

ステレオと知らずに体験しても自然で特に言うことはない、と受け取れなくもないですが、ステレオの振動でも、リアルというよりは違和感を減らす程度の意味合いが強いので、モノラル→ステレオ対応のコスパは振動なし→モノラルに比べると良くない感はあります。

このへんの話は、扇風機も正面から 2 段階でなんとかなる( VR向け風量制御の先行事例とイルカラスでの実現方法模索 - Togetterまとめ )という話と近い領域な感じです。

振動は、例えば左から右に振動を移動させている間はそれがよくわかる一方、ずっと右だけ振動させていてもあまり右だと感じにくいといった性質があると思います。(私個人の感覚に基づきますが、人間の感覚全般にそうした性質があるような認識をもっています)

そのため、カーブ時の振動の計算式にメリハリをつけたり、飛行機にトラブルが生じるシーンでのエンジン停止→再開など、なるべく変化をつけるような演出を意識しています。

(VR 空間内での移動に応じた振動のフィードバックがあることによる酔いの低減効果、もしかしたら多少は期待できるかも…と思ったりもしますが、十分な比較データがないと何とも言えないですね。東京オッキューランド出展時のアンケート集計を見る分には、激しく動くコンテンツの割には酔われにくい模様です)

おわりに

既存コンテンツへの追加コストが低い、というこのデバイスの大きな魅力の一つを殺している感がありますが、ステレオ化自体は悪くないんじゃないかと思います。コスパは低下します。

あと、音声デバイス別系統に分けるくらいなら、Arduino + 振動モーターみたいな選択肢もありそうですね…。

2015年4月12日日曜日

[Unity][OculusRift]高解像度なスクリーンキャプチャをとるやつ


ポスター印刷用にディスプレイ解像度以上のスクリーンキャプチャが必要になったので、簡単にできるやつを作りました。


  • 適当なオブジェクトにつける
  • Minimum WidthMinimum Height を指定(デフォルトで A1 縦 72dpi 用)
  • Target Camera を指定
  • Oculus Rift のカメラだったら View Port Width0.5 に変更
  • Shitf + P で指定パス以下にキャプチャ(キー変更可能)


Windows 8.1, Unity 4.6 + Oculus SDK 0.4.1 と 0.5.0.1 の Oculus 用カメラと通常カメラで動作確認しています。

(Application.CaptureScreenshot の方は、拡大しても粗くなるだけみたい → 再度試したら粗くならないっぽい(2015/6/26, Unity 5.1.1p1 without Oculus SDK))


こちらに大変お世話になりました! :
高画質なスクリーンショットを撮影する - テラシュールブログ

メモ :
みんなの知識【ちょっと便利帳】 - 用紙サイズのピクセル値一覧



2015/6/26 追記 : Application.CaptureScreenshot について

2015年1月2日金曜日

PlayStationMoveをPCかつネットワーク経由で使えるPSMoveServer

PlayStation Move を PC で、かつネットワーク越しで使える PSMoveServer というものを作りました。

概要

PlayStation Move というモーションコントローラーをある PC と接続してサーバーを起動し、同一 PC または他の PC 上の別のアプリケーション(クライアント)から利用できるソフトを作りました。

これを使うと、PlayStation Move を接続するのが困難な Windows 8 や Android(未確認ですが) でも簡単に利用することができます。

また、クライアント側で面倒な実装をしなくても、サーバー側でコントローラーの設定変更、状態の監視などを行えて便利です。

クライアントはとりあえず Unity 用のみ用意しています。

PS Move について


PlayStation Move (以下 PS Move) は PS3 用のモーションコントローラーで、加速度、ジャイロ、磁気による姿勢の取得といくつかのボタン操作、バイブレーションが可能です。あと光ります。

また、PlayStation Eye (以下 PS Eye) をはじめとするカメラと組み合わせることで、コントローラーの位置トラッキングも行うことができます。

PlayStation®Move(PS Move) | プレイステーション® オフィシャルサイト



有志の API を使えば PC にも Bluetooth で接続して利用することができます。

PC でモーションコントローラーとして利用可能なデバイスはいくつかありますが、位置トラッキングまで行えるものは限られています。

Leap Motion のツールトラッキングを使う、何らかのモーションコントローラーと Kinect を組み合わせるといった選択肢があり、それぞれに異なる利点がありますが、PS Move + PS Eye の利点は合わせて 6000 円程度と安価なことと比較的安定した姿勢取得、バイブレーションなどが挙げられます。

おそらく最大の弱点は明るい部屋で位置トラッキングの精度が出ないことです。ただ、ここの検証はまだあまりできていません。

PS Move 単体を 3000 円強で無線で姿勢を取得できるデバイスと見てもお得感があります。

Move.me について

PS Move をネットワーク越しで使う、というのは公式で Move.me というサービスがあり、PS3 本体と北米(?)アカウントがあれば使えるみたいです。こちらはあまり調べていません。

PS Move API と PC での利用について

PS Move と PS Eye を PC で使うには PS Move API を使う方法があります。

ペアリングから利用まで、はじめは英語だったり情報があまりまとまっていなかったり環境が限られたりで苦労するかもしれません。

非常にざっくりと書いておくと、Windows 7 (64bit) なら
  1. USB で繋いで API 付属の psmovepair.exe を実行(落ちたらまたやる)
  2. iPi Recorder で Bluetooth ペアリングできるようにする
  3. magnetometer_calibration.exe で磁気キャリブレーションする(気長に。あまりに進まなければ Ctrl + C でやり直し。ドリフト回避のため重要)
  4. PS Move API が使える
です。

Windows 8 以降でのペアリングは OS 標準の Bluetooth ドライバではかなり厳しく、MotionInJoy というドライバ(ちょっとおすすめし辛い)を入れても相性が良くないと厳しい、といった感じです。

位置トラッキング用のカメラは一応 PS Eye 必須ではありませんが、PS Eye を使うなら CL Eye Driver ($2.99) を入れると良いようです。

Mac は試していませんがこちらの記事が参考になるかもしれません。Ocufes で早くから PS Move を使ったコンテンツを複数展示されている @WheetTweet さんの記事です。


ペアリングの際お世話になったページを貼っておきます。



PS Move API の Unity ラッパー。ちょっとおかしなところがありましたがかなり参考にさせて頂きました。



(なお、API 自体にもリモート PC 上のデバイスをローカルデバイスのように扱う機能が含まれているのですが、試したところ動きませんでした。github の最新版も確認しましたが、Winsock 初期化も行われていないなど少なくとも Windows 版はメンテされていない印象を受けました。ちなみに初期化をしただけではダメでした。これを直すとプロジェクトに貢献できそうな気がしたのですが、今回はサーバー側 GUI も欲しかったので独自に作ることにしました。)

PSMoveServer について

力尽きたし時間も尽きたので雑です…

ダウンロード : PSMoveServer_0.1.1.zip (アルファ版)

PS Move API を同梱していないので、別途ダウンロードして Plugins に libpsmoveapi.dll を入れてください。位置トラッキングも行うなら libpsmoveapi_tracker.dll も入れてください。

ライセンスは将来的に修正 BSD か MIT になるはずです。

動作環境 :
サーバーは Windows 7 (64bit) で確認
クライアントは Windows で確認(他でも使えると思いますが、ビッグエンディアンな Mac はサボっているのでダメです…じきに直します。Android もビッグかも)


PSMoveServer.exe を起動


Bluetooth ペアリングまでは別途済ませておいてください。

位置トラッキングするなら UseTracker をオン、カメラが複数あるなら ID を指定(0 ベース)。PS Move のスフィアをカメラに向けておきます。

Initialize を押します。PC 初回はよく PS Move API が落ちるようです。何度か起動し直してください。

Fusion の Position も異常な値や NaN になることがあります。何度か Uninitialize / Initialize を繰り返すと直るようです。

PS Move が勝手に動くのが落ち着いたら、ボタンを手前、スフィアを上に向けて ResetOrientation を押します。

クライアント側プロジェクトに unitypackage をインポート、Scenes/ClientDemo を見る。PSMoveClient.cs がサーバー、PSMoveClientObject.cs が同期して動くオブジェクトです。


今後の ToDo:
通信周りをほんとうにサボっているのでなんとかします…

Mac 版のサーバーが欲しいひとは僕に Macbook Air をおくろう!!1
(bootcamp したほうが安いですね)

カメラから取得した画像も出したいです。

ツナとタイカレー缶について

PSMoveServer は無料でご利用いただけますが、作者にツナとタイカレー缶を送ることもできます。


または、利用した作品や開発に役立つ情報を公開していただけると大変喜びます。