クリぼっちなので「何がクリスマスじゃあい！」をVRでやってみたかった【Unity+SteamVR】

## はじめに

**何がクリスマスじゃあい！ちくしょう！**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/80abe304-05e1-56ab-a3b7-f5410c83001b.gif" alt="クリスマスツリーを投げるやつ" width="680px">
メリークリスマス、@Payayayayaです。

[ディップ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/dip-dev)の最後の記事になります。
[昨日の記事](https://qiita.com/tato_lol/items/44401ce104a79991b8f7)もクリスマスらしい記事なのでクリスマスっぽい記事にしました。

## やってみること

毎年この日になると話題になる**アニメ「巨人の星」のあのシーン**のマネをしたいのですが、リアルではなかなかできないのでVRでやりたい。
UnityへのSteamVRのインポートからクリスマスツリーを投げるまでやってみます。

ちなみに、「何がクリスマスじゃあい！」と言ったのは星飛雄馬ではないです。

## 環境

- Unity (2019.4.16f1 LTS)
- SteamVR (beta 1.15.14)
- SteamVR Plugin (2.6.1)
- VIVE Cosmos Elite

---

## SteamVR Pluginのセットアップをしよう

まずはUnityのプロジェクトをVR環境で実行できるようにします。
今回はValveが公開している**SteamVR Plugin**を利用します。

### SteamVR Pluginのインポート

アセットストアで「SteamVR Plugin」と検索し、`Add to My Assets`でダウンロードします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/1b0833a0-00fc-45a9-ca26-67103938d516.png" alt="Unityアセットストア" width="680px">

Unityのメニューバーから`ウィンドウ`→`Package Manager`と開き、`My Assets`を開いてSteamVR Pluginをインポートします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/60d7c497-6305-ffbb-4f80-000874e97455.png" alt="Package Manager" width="680px">

インポートするものを選択するウィンドウが表示されるので、特に変更せず`インポート`を押しインポートします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/6ef172fe-6220-08a9-8ac7-7d30d2d140e8.png" alt="import window" width="240px">

以下のようなウィンドウ（SteamVRの推奨設定に変更してみない？的なやつ）が表示されるので、`Accept All`を押しUnityプロジェクトの設定をSteamVRの推奨設定に変更します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/3bd61db9-29ec-8a45-fd91-3ac07ba1d097.png" alt="推奨設定にするウィンドウ" width="300px">

推奨設定に変更すると、**You made the right choice!**とダイアログが表示されます。

### SteamVR Inputの設定

Unityのメニューバーから`ウィンドウ`→`SteamVR Input`を開くと、以下のようなダイアログが表示されます。
`Yes`を押すとサンプルの入力設定JSONファイルがコピーされるので、`Yes`を押します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/81e0c9db-34dd-1152-5c37-c31f9898145d.png" alt="サンプル入力設定" width="300px">

JSONファイルのコピーが終わったら、表示されたSteamVRの入力設定ウィンドウの`Save and generate`を押します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/515f779f-f04f-9fc0-a890-1b3cd048ca43.png" alt="入力設定ウィンドウ" width="680px">

これでVIVEコントローラー等の入力をUnityで利用できるようになります。

---

## SteamVR PluginのInteractionシステムでオブジェクトを投げよう

### プロジェクトをSteamVR上で実行してみる

`SteamVR Plugin`のインポートが完了しているので、SteamVR上で実行する手順はとてもかんたんです。

最初から存在する`Main Camera`オブジェクトをシーンから削除し、`Assets/SteamVR/InteractionSystem/Core/Prefabs`内にある`Player`プレファブをシーン上に配置します。

↓これです↓
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/ffd65ea0-11b4-f929-c81d-f302956a907c.png" alt="Playerぷれふぁぶ" width="680px">

#### 実行画面

`再生`ボタンを押すと、シーンがSteamVR上で実行されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/417401fb-121b-3108-7dfe-d556d937f451.gif" alt="動いて喜ぶわたし" width="680px">

便宜上Unity上のゲーム実行画面のスクリーンキャプチャですが、ちゃんとヘッドセット上でもシーンが描画されています。
ヘッドセットの動きに合わせてシーンが描画されており、操作するVIVEコントローラーが手として表示され、
コントローラーを動かしたり、ボタンを操作することで手の形を変えられるようになっています。

### オブジェクトを投げる

SteamVRのInteractionシステムを利用することで、簡単にオブジェクトを投げることができます。

まずは投げたいオブジェクト（今回は`Capsule`オブジェクト）を用意します。
（ついでに床として`Plane`（平面）、台として適当な`Box`も用意します。）
オブジェクトの追加はヒエラルキー上で右クリック→`3Dオブジェクト`→`任意のオブジェクト`と選択して追加できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/8024a43d-55f8-9a42-a3fa-09c701d7cc2b.png" alt="動いて喜ぶわたし" width="680px">

投げたいオブジェクトに以下のコンポーネントをアタッチします。（Throwableをアタッチすることで他2つも自動的にアタッチされます。）

- Throwable（スクリプト）
- Interactable（スクリプト）
- Rigidbody

これらをアタッチすることで、対象のオブジェクトを掴んで投げることができるようになります。

#### 実行画面（※画面酔い注意）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/9dbe7fec-f1f2-0153-00b1-18da299901ad.gif" alt="オブジェクトを投げるわたし" width="680px">

デフォルトの操作設定では、実行中にオブジェクトの近くでコントローラーの`トリガー`を引くと、オブジェクトがゲーム内のコントローラー位置に追従し、`トリガー`を離すと追従しなくなります。
コントローラーを動かしている最中にトリガーを離すことで、オブジェクトを慣性により投げることができます。
とってもかんたんですね！

---
## クリスマスパーティーの準備をしよう

### クリスマスツリーを用意する
まずはクリスマスツリーを用意します。

今回アセットストアでFreeのものがあったので[こちら](https://assetstore.unity.com/packages/3d/props/interior/christmas-decoration-props-159202)を使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/bcd1920b-fd02-f620-51ed-dd4d3b81f6c7.png" alt="クリスマスデコレーションプロップスアセット" width="680px">

アセットのインポートは`SteamVR Plugin`のときと同様に`Package Manager`から行えます。

ツリーの土台として`Cylinder`オブジェクトを使います。
空のオブジェクトを作成し、その子要素としてインポートしたアセット内の`ChristmasTree`プレファブと、土台とする`Cylinder`オブジェクトを配置してあげます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/88dead3d-9549-2478-b47f-a7ac57c8a6e7.png" alt="じゃーん！クリスマスツリー！" width="680px">
手で持てるように、適当なサイズにした`Box Collider`を`ChristmasTree`プレファブと、土台とする`Cylinder`オブジェクトにアタッチし、
親要素として作成した空のオブジェクト（↑の画像では`Tree`オブジェクト）に`Throwable`スクリプト、`Interactable`スクリプト、Rigidbodyコンポーネントをアタッチしておきます。

### 部屋を用意する

`Box`オブジェクトを伸ばしたり縮めたりして気合で部屋を作っていきます。

割れるガラスもぜひ欲しいところですので、こちらを利用します。
[![OskarSigvardsson/unity-delaunay - GitHub](https://gh-card.dev/repos/OskarSigvardsson/unity-delaunay.png)](https://github.com/OskarSigvardsson/unity-delaunay)
ドロネー三角形分割から得たボロノイ図をメッシュの分割パターンに用いるものです。
`Assets/Plugins/Delaunay`フォルダと`Assets/Scripts/BreakableSurface.cs`スクリプトをインポートします。

インポートした`BreakableSurface`スクリプトを**x, y方向に大きくz方向に薄い**オブジェクトにアタッチします。
次に、アタッチしたオブジェクトの`Collider`を`Mesh Collider`に変更し`凸状にする`にチェックを入れます、
最後に、`Rigidbody`コンポーネントをアタッチして`Use Gravity`にチェックを入れます。

こんなかんじに。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/5ba20ea9-3abc-f79f-2d2c-c59c402b22e3.png" alt="投げるコンポーネントの設定" width="300px">

あとは`Mesh Renderer`コンポーネントの`Material`を半透明なマテリアルにすれば、リアルタイムに割れるガラスが再現できます。
割れるガラスを使って窓を作ったり、`Cube`や`Cylinder`の形状を変えて机や椅子、ケーキっぽいものを用意して**それっぽく**します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/fd1309c8-13e0-dab2-d8ff-185ef9be664b.png" alt="パーティー会場" width="680px">


### 夜にしたり雪を降らせたり

パーティは18時からですので、シーンを夜にしてみます。
[こちら](https://assetstore.unity.com/packages/vfx/shaders/ultra-skybox-fog-115414)のアセットを利用して、SkyBoxに夜空のマテリアルを設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/9d64aaf7-b44f-8503-4771-6054fabcefc8.png" alt="Ultra Skybox Fogアセット" width="680px">

アセットのインポートが完了したら、Unityのメニューバーから`ウィンドウ`→`レンダリング`→`ライティング設定`を開きます。
開いたウィンドウの`スカイボックスマテリアル`に、インポートした`Ultra Skybox Fog/Materials/satera_night_8k`を設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/1f174da1-809d-9b04-bf74-cbed0c9b7c09.png" alt="ライティングの設定" width="480px">
最初からシーンに存在する`Directional Light`の`強度`を下げることで、夜っぽいシーンにできます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/40f69fab-a901-9929-aa4b-78dad7f70e75.png" alt="夜に見せる" width="680px">
いい感じですね。

せっかくなので雪を降らせましょう。
Unityの`パーティクルシステム`を使えば簡単に実装できます。
ヒエラルキー上で右クリックし、`エフェクト`→`パーティクルシステム`を選択して追加します。

`Inspecter`の`Transform`でX方向の回転を90に設定することでパーティクルが重力方向に移動するようになります。
このままだと円錐状にパーティクルが放出されるだけなので、`Particle System`コンポーネントの`形状`を`Box`にし、位置や拡大/縮小をイジって雪を降らせたい範囲に設定することで、雪っぽくパーティクルを降らせることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/a1bbc92d-268c-f997-b3ef-26ffb8a326d4.gif" alt="Let it snow!" width="680px">

## クリスマスを楽しもう

準備が整ったら、あとは招待状を送った方々が会場に来るのを待つだけです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/8e1d453c-69d8-c459-e34c-bf785a76f5ed.png" alt="しかし誰も来ない" width="680px">

...

...

...

...

結局、誰も来なかったという事か…！

**うおおおおおおお！！**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/a2e7f760-962c-22d8-982e-3cd0aeffef5f.gif" alt="何がクリスマスじゃあいVR視点" width="680px">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/889c7f86-0256-bc11-6564-e74c890bbcb0.png" alt="完" width="680px">
ちくしょう...

## ビルドしよう

Unityのメニューバーから`ファイル`→`ビルド設定`を選択してビルド設定ウィンドウを開きます。
最初からある`Sample Scene`を`Main`にでも改名して、ビルド設定ウィンドウの`シーンを追加`でMainシーンを追加します。
`ビルド`を押下すればビルドが始まり、exe形式の実行できるアプリケーションが完成します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/e7edd4c7-0907-f000-787e-f92aff9fac91.png" alt="ビルド設定" width="480px">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370039/6eedb09d-ee14-a68c-f729-e25fc310d135.png" alt="ビルド後のファイルとか" width="300px">
ビルドが完了するとこのようにフォルダ/ファイルが生成されます。
生成された.exeファイルを実行することで、いつでもクリスマスツリーを投げることができるようになりました。

## おわり

Zoomのバーチャル背景で遊んでるときにふと思いついたアイデアでしたが、現実ではなかなか真似できないこともVR世界で簡単に再現できるのは楽しいですね。
SteamVR Plugin 2.0以降のInteractionシステムのおかげで、1行もコードを書かずに実現できたことはとても良かったです。

いろいろと準備している時に、クリスマスパーティーの準備をしている星飛雄馬の気持ちまで体感できたような気がします。
みなさんもぜひやってみてください。では。