読者です 読者をやめる 読者になる 読者になる

艦長VR2

進捗があったので追記します。

重い

夕雲型モデル、非常に出来がいいのですが、それゆえに非常にマシンパワーが逼迫してしまい
fpsが維持できなかったため、別のモデルに変更しました。

モブ駆逐艦をお借りしています。

f:id:izugch73:20161209192053p:plain

海上

船なので海の上に乗せましょう。

メニューの Asset > Import Package > Environment でAssetをimportすると、
Standard Assets内に環境を作れそうなプレハブが一通り入ります。

ここではWater4Advancedを使用しました。

それっぽい大きさになるようにスケールを設定して船のやや下部に配置します。

f:id:izugch73:20161209192235p:plain

星空

せっかく隣に艦長がいるので、雰囲気を出してみます。

星空のSkyboxを設定しましょう。

Asset Storeからムードの出そうなSkyboxをダウンロードします。

https://www.assetstore.unity3d.com/jp/#!/content/25142

Skyboxをいじるには、メニューのWindowからLightingを選択し、Skyboxを先ほどダウンロードしたマテリアルに変更します。

f:id:izugch73:20161209192525p:plain

これで無機質だった空がそれっぽくなりました。

f:id:izugch73:20161209192646p:plain

艦長を動かす

ボッ立ちだった艦長にアニメをつけたいと思います。

アニメーションはあまり詳しくないのですが、MMD4MecanimでMMDデータをUnity用Prefabに変換するときに、
vmdを一緒に登録して変換することでモーションデータもUnity側にもってこれるようです。

f:id:izugch73:20161209193225p:plain

ただ顔の作りが違う(物理)せいか、モーフがうまくいかず、顔がうまく動きません。。。
ここはがっつり自分で作る必要がありそうなので、もう少し勉強が必要です。

youtu.be

海も動いてますね。

コントローラの情報を取得する

Viveはルームスケールも目玉でありながら、PSVRやOculus Touchに先じ、コントローラのあるVR機器でもあります。

せっかくなので使いましょう。

何に使うか、、、というところですが、実物大(?)の船のモデルがあるので、
ある程度動き回れるような仕組みにしたいですね。

というわけで、移動することを検討してみたいと思います。

移動する

VRでの移動の方法について

VRで自分が移動するときにどうしても伴う問題が「酔い」です。

視覚情報と体の感覚に乖離が発生するとあっさりVR酔いが発生してしまうので、VRの先駆者はこの問題の解決に躍起になっています。

たとえばコントローラでボタンを押している間視界が前進するなどの方法では、非常に酔いを誘発しやすいです。

基本的に移動中は視界を狭くするか全く遮るなどして、体の感覚以外の視点移動を極力減らすべきです。

方法

と、だらだらと考えたところで、世に出す製品でもないので、
プレゼンスは低下しても移動できる喜びを感じられればいいかなと、今回は「瞬間移動」とします。

瞬間移動はその名の通り一瞬で視点を移す方法です。

どう考えても物理的にあり得ないのでプレゼンスの低下は避けられませんが、
画面がヌルッと動くこともないので酔いもあまり発生しません。

何より実装が楽なのでこれでいきます。

ゲーム内の手段ですが、何か物を投げてその着地点に視点が移動するようにしたいと思います。

物を投げる

物を投げるには、コントローラから加速度を取得し、その値をゲーム内オブジェクトにVelocityとして加えてやればよさそうです。

SteamVRのサンプルに物を投げるコードがあるので、それをまるっとパクお借りしましょう。

// デバイス情報を得る
var device = SteamVR_Controller.Input((int)trackedObj.index);

device.velocitydevice.angularVelocityで加速度と回転加速度が取れるので、
これをゲーム内オブジェクトにそのまま貼りつけます。

// ゲーム内の剛体に加速度を転送する
rigidbody.velocity = device.velocity;
rigidbody.angularVelocity = device.angularVelocity;

まぁだいたいこんな感じでやればできそうです。

投げる時のコードはごそっとサンプルを模しているので、
詳しくはSteamVRをインポートしたときに一緒に入ったであろうSteamVR_TestThrowシーンを参照ください。

投げるものを決める

ただの玉でもいいんですが、せっかくAdvent Calendarなので(?)、マサカリにしましょう。

f:id:izugch73:20161209201823p:plain

これを投げることにします。

衝突を得る

何か投げるとして、それが着地したところのポジションを得なければなりません。
ということは、マサカリと船の衝突を判定しないといけません。

衝突の判定にはコライダーを使用します。
マサカリにはざっくりとコライダーをつけておきました。
先ほどの画像の緑のカプセルのような形がコライダーです。

さて、問題は船です。

これだけの大きさの船に緻密なコライダーを手作業で貼っていくのはさすがに厳しいのでアセットを使います。

https://www.assetstore.unity3d.com/jp/#!/content/15058

このSAColliderBuilderは、3Dオブジェクトの形にコライダーを貼ってくれる優れものですが
コライダーとはその名の通り衝突を常に監視するので、複雑であれば相応に処理が重くなります。

今回はほかに重い処理もしていないので、がっつり貼っておきます。

f:id:izugch73:20161209202012p:plain

そしたら衝突時のコードを書きます。

    // マサカリに貼る
    void OnCollisionEnter(Collision collision){
        GameObject.Find("[CameraRig]").transform.position = this.gameObject.transform.position;
        Destroy(this.gameObject);
    }

OnCollisionEnterで衝突時に動きます。

[CameraRig]が現在の視点(正確にはプレイエリアの足元)なので、衝突した位置(=マサカリの現在地=this.gameObject.transform.position)を代入します。
そしたらマサカリには消えてもらいましょう。
ちなみにFindは重いので本来衝突都度実行すべきコードではないんですが許してください。マサカリガード。

youtu.be

移動できてそうですね。

動画

※他人視点のVR動画は酔いやすいのでご注意ください。

youtu.be

お借りしました

モブ駆逐艦
モブ駆逐艦1945&輸送船セット - BowlRoll

MMD用汎用立ちモーション
MMOP用素朴立ちモーション配布 - BowlRoll

マサカリ(斧)
https://www.assetstore.unity3d.com/en/#!/content/56928

おわり

海の仲間は家族なんでぃ