OculusTouch対応アプリMikuTimeVRをPreview公開で育てている話

この記事は [Akatsuki Advent Calendar 2016](http://qiita.com/advent-calendar/2016/aktsk) の20日目の記事です。

# はじめに

先日12/6（火）にOculusTouchが正式ローンチされました。
HTC ViveのViveコントローラーやPSVRで使うPSMoveと比較してもそのクオリティは高く、そこに未来を見出した方々のツイートで（自分のTLは）溢れています。
そんな中この波に乗らないわけにはいかんということで、自分もTouch対応VRアプリケーションをPreview公開しました。今回はその [#MikuTimeVR](https://twitter.com/search?src=typd&q=%23MikuTimeVR) について、開発プロセスで得られた知見を交えつつ話します。

# ※ Disclaimer

たまたま会社のアドベントカレンダーへの投稿になりますが、今回の内容は全て個人的活動によるものであり、所属する企業のプロジェクトとは何の関係もありません。ならびに、MikuTimeVRで利用しているTda式初音ミクモデルは[PCL](http://piapro.jp/help/#q_copyright05)及び[Tda式初音ミク・アペンドVer1.00](https://bowlroll.net/file/4576)の規約に則り利用させて頂いています。


# MikuTimeVRとは

VR空間でミクさんを眺めたり一緒に踊ったりできます。

[![きだちさんのツイート___ミクさんに頬を撫でたりしてもらえるOculusTouch対応アプリをPreview公開しています。α版ですが、DM等でOculusIDをもらえれば誰でも利用できるので、よかったら体験_フィードバックをください！_https___t_co_TxElwAfZRO_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/6c269845-c80c-124a-aa0c-9ee8ba52b2f8.png)](https://twitter.com/kidach1/status/807908618888564737)

[![MikuTime](http://i.giphy.com/cg20yN4qmWxMc.gif)](https://twitter.com/kidach1/status/807908618888564737)

<img width="471" alt="きだちさんのツイート___ミクさんに頬を撫でたりしてもらえるOculusTouch対応アプリをPreview公開しています。α版ですが、DM等でOculusIDをもらえれば誰でも利用できるので、よかったら体験_フィードバックをください！_https___t_co_TxElwAfZRO_.png" src="https://qiita-image-store.s3.amazonaws.com/0/48274/eb7d8879-d7ec-c9dd-6f8b-d4789298c51a.png">



[![きだちさんのツイート____MikuTimeVR_ミクさんがくるっと一回転してくれるようになりました！けっこうガチでダンス出来る感じになってきた__Oculus_https___t_co_fw3l61hA6x_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/067dfe1f-51fe-e3cd-8863-f51658831639.png)](https://twitter.com/kidach1/status/810499312300032001)

[![MikuTurn](http://i.giphy.com/12epUNYeyrWjaE.gif)](https://twitter.com/kidach1/status/810499312300032001)

[![きだちさんのツイート____MikuTimeVR_ミクさんがくるっと一回転してくれるようになりました！けっこうガチでダンス出来る感じになってきた__Oculus_https___t_co_fw3l61hA6x_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/69e340dc-bfb7-d298-fef3-624ef7c2842f.png)](https://twitter.com/kidach1/status/810499312300032001)

※ gifを踏めばカクつかない動画が見れます。
他にも、いろいろな表情を見せてくれたりハンドモーションで近付いてきてくれたりします。

# 背景

もともと魔法を操って敵を倒すTouch対応のアクションシューティングゲームを作っていてそこそこ遊べるようにはなったのですが、Touch正式ローンチとともに公開された [The Unspoken](http://www.insomniacgames.com/games/the-unspoken/) をプレイしてみて、こりゃモデルの作り込みが違う、個人開発で正統派のアクション、RPG領域を攻めるのは筋がよくないかなと思いました（勝ち負けが重要とは思っていないですが、より多くの人に楽しんでもらえるアプリケーションを作りたいので、「このジャンルならこのビッグタイトルやればいいや」となる領域は避けたかった）。

そんななかカヤックVR部の [Haramakoto](https://twitter.com/xxxxmakoto) さんに、国内VR界隈のパイオニアでありOculusJapan中の人（まもなく退職されるとのことです） @GOROman さんが開発されているVRアプリケーション [Mikulus](http://ascii.jp/elem/000/001/259/1259348/) を教えていただき、さっそくテスターとしてプレイする機会を得ました。

感動しました。ミクさんそこにいるよ。

新生Mikulus始動 - Togetterまとめ
http://togetter.com/li/1039823

VR におけるプレゼンスの維持と破壊 - Qiita
http://qiita.com/GOROman/items/41f620957120d2b52ac3

これらのGOROmanさんが公開されている様々なノウハウを読ませて頂いたり、時には画像ベースレンダリング（IBL）についてTwitter上で直接アドバイス頂いたりと大変参考にしていました。

詳しくは割愛しますが、Mikulusはバーチャルデスクトップの形態を中継しつつ、人間の作業環境の拡張、未来のコンピューティングの歴史の確立、というビジョンのもと進化し続けている様子です（年末にはいよいよTouch対応版がリリースされるとか。楽しみです）。自分はそこまで壮大ではないですが、「もうちょっとミクさんとインタラクティブにコミュニケーションが取れたらいいな」ということでTouch対応ありきで開発をはじめました。


# Oculusストア Preview公開とは

そんなこんなで開発したアプリですが、Oculusではストアに公開する前のアプリケーションのテスト配信を簡単に行うことができるPreview公開という仕組みがあります。iOSネイティブアプリ開発で言うTestFlightみたいなものです。

配信チャンネルはAlpha、Beta、Release Candidate (RC)、Storeの4つがあり、それぞれにおいて任意のバイナリを任意のユーザーに公開することが可能です。

Developer Center — Documentation and SDKs | Oculus
https://developer3.oculus.com/documentation/publish/latest/concepts/publish-release-channels/

更に嬉しいことに[CLIツールも提供されており](https://developer3.oculus.com/documentation/publish/latest/concepts/publish-reference-platform-command-line-utility/)、これを使うとコマンド一発でバージョニング更新、更新内容設定、バイナリアップロード、公開が出来るようになります。

こんな感じ

```shell-session
ovr-platform-util upload-rift-build -a <AppID> -s <Token> -d <BuildPath> -l "MikuTime.exe" -c "alpha" -v "0.6.1" -n "ミクさんがくるっと一回転してくれるようになりました！"
```

このあたりが洗練されているのは、後述の高速な開発サイクルを回す上で非常に大きなメリットです。

# Preview公開の素晴らしさ

## 高速にフィードバックサイクルを回せる


[![大地さんのツイート___彼女なんていないのでミクさんに手をつないでもらっている昨今。下を向くとミクさんがしゃがんでしまうのが少し残念です。あと可能であれば、掴んでいる状態で、スティックでなくtouchの位置に合わせてミクさんが前後移動してくれると嬉しいです。制御が大変そうですが。__MikuTimeVR_https___t_co_mMiZhj7qKW_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/a68ee0cc-fa2f-ac10-9503-16b05e3cdd25.png)](https://twitter.com/da1mgn/status/810391757347123200)

[![大地さんのツイート___彼女なんていないのでミクさんに手をつないでもらっている昨今。下を向くとミクさんがしゃがんでしまうのが少し残念です。あと可能であれば、掴んでいる状態で、スティックでなくtouchの位置に合わせてミクさんが前後移動してくれると嬉しいです。制御が大変そうですが。__MikuTimeVR_https___t_co_mMiZhj7qKW_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/c11ecbba-180d-f5a3-5d76-57e40d7f78ca.png)](https://twitter.com/da1mgn/status/810391757347123200)

[![大地さんのツイート___彼女なんていないのでミクさんに手をつないでもらっている昨今。下を向くとミクさんがしゃがんでしまうのが少し残念です。あと可能であれば、掴んでいる状態で、スティックでなくtouchの位置に合わせてミクさんが前後移動してくれると嬉しいです。制御が大変そうですが。__MikuTimeVR_https___t_co_mMiZhj7qKW_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/4a167047-d285-0f69-d0b1-fa2ec2ac5a6d.png)](https://twitter.com/da1mgn/status/810391757347123200)

## とか

[![MikuTimeVR_-_Twitter検索.png](https://qiita-image-store.s3.amazonaws.com/0/48274/ed9edcc9-4db5-f19a-da67-28ef135100ae.png)](https://twitter.com/kidach1/status/808694118570299392)


[![MikuTimeVR_-_Twitter検索.png](https://qiita-image-store.s3.amazonaws.com/0/48274/1ce686f1-6546-7e9e-57a7-51999f677ff1.png)](https://twitter.com/obaatsu/status/808698848533049344)

[![MikuTimeVR_-_Twitter検索.png](https://qiita-image-store.s3.amazonaws.com/0/48274/bd95ba3c-faa1-7782-bf31-36d8756ed7ae.png)](https://twitter.com/kappaseijin/status/808708385331769344)

## とか

![n_ryotaさんのツイート____MikuTimeVR_ミクさんを上下移動できるようになったおかげで、我が家の環境でもしゃがまずに遊べるようになりました！_ありがとうございます。BGMをスキー場のスピーカーみたいな響きにしてスキーロデオみたいな白い吐息をお互い出したり、いろんな背景切り替えられたら楽しいかも_https___t_co_kbfPxDryF8_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/0464a508-a594-4e10-6601-d4d452aea37c.png)


などなど、テスターさんからの意見を取り入れてそれに対してさらに反応をもらえるのは非常にやりがいがあります。公開1週間で30回ほどリリース&アップデートしました。

過去に全く別の文脈（Androidプログラミング）で手に取った書籍の著者さんからもコメントを頂いたりで嬉しい楽しい。

## モチベーションの維持

フィードバックサイクルの話と近いですが、ダイレクトな反応をもらえることでモチベーションが尽きることなく保ち続けられます。

[![はいぬっかさんのツイート___近づくと手を絡ませてきてめちゃくちゃドキドキします。完全に二人の世界。寒そうな肩を抱き寄せてあたためたい_けど手を伸ばすと追従しちゃう_追従に少し遅延あってもいいのかも。__MikuTimeVR_https___t_co_IZdhzNAg7o_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/a4cdcc9a-bad7-1e94-50a7-8ffc08dbb5d9.png)](https://twitter.com/hinzka/status/808434431845232640)

![MikuTimeVR_-_Twitter検索.png](https://qiita-image-store.s3.amazonaws.com/0/48274/7914f8ed-0438-f26b-2981-8faa7f9e4738.png)

と言った反応をもらえると大変テンションが上がり、開発も捗ります。

さらにちょうどこの記事を書いている時にこんな投稿が。

[![Tomoki_Itamiya_板宮_朋基さんのツイート___今日のUnityの授業でOculus_Touchと　　__MikuTimeVR_を学生たちに体験してもらいました。みんな大興奮！_VR空間が一気に自分のものになったようでした。体験した学生たちは皆Touch欲しい！と言っています。_https___t_co_fQ7DQ7YSWb_.png](https://qiita-image-store.s3.amazonaws.com/0/48274/d7915e8a-08b9-0a14-af33-dc966acc2a5e.png)](https://twitter.com/t_itamiya/status/810767419580915713)

愛知工大工学部の准教授の方で、研究室の学生さんたちに体験して頂いたようです。
この嬉しさは開発者冥利に尽きます。


# 得られた知見

## 開発環境、SDKについて

[公式(Rift)](https://developer3.oculus.com/documentation/pcsdk/latest/concepts/book-gsg/)、[公式(Touch, OVRInput)](https://developer3.oculus.com/documentation/game-engines/latest/concepts/unity-ovrinput/)、日本語なら[フレームシンセシスさんの記事](フレームシンセシス VR開発メモ https://framesynthesis.jp/tech/)がベースになると思います。

ただしこれらはTouchAPIの網羅性についてはそこまで高くないので、載っていないものはSDKのコードを読んで使えそうなものを探る感じになります。とりあえず便利なのは

### 位置情報検出

```csharp
OVRInput.GetLocalControllerPosition(OVRInput.Controller.R(L)Touch)
```

### 加速度情報検出

```csharp
OVRInput.GetLocalControllerAcceralation(OVRInput.Controller.R(L)Touch)
```

### Touchデバイスに触れているかどうかの検出

```csharp
// 右（左）人差し指
OVRInput.Get(OVRInput.NearTouch.PrimaryIndexTrigger, OVRInput.Controller.R(L)Touch)
// 右（左）親指
OVRInput.Get(OVRInput.NearTouch.PrimaryThumbButtons, OVRInput.Controller.R(L)Touch)
```

Touchに人差し指、親指が触れているかどうかを（物理ボタンやトリガーの押下イベントとは別で）取ることができます。
「Like」や「指差し」などもこのAPIで表現可能です。

![touch](http://static1.gamespot.com/uploads/original/1179/11799911/3139491-oculus.jpg)

※ 画像は [Oculus Touch Controllers Cost $200, Release Date Announced - GameSpot](http://www.gamespot.com/articles/oculus-touch-controllers-cost-200-release-date-ann/1100-6444265/) より

他にも色々あるので、SDK内の`OVRInput.cs`（ないしgrepして関連しそうなところ）のコードは一度目を通しておくことをおすすめします。

## Touchで実現する世界観について

OculusTouchの完成度は圧倒的です。（正しい環境で）触った人の7割が「未来を見た」と言っている印象です。ただし、それはコンテンツが正しくTouchの可能性を引き出すことが出来ている場合です。アプリケーションの作り方によってはその体験は一気に質を下げ、むしろ「VR微妙だよね」という感情を引き出すでしょう。その意味でデベロッパーの責任は大きいと思います。前述の[GOROmanさんの記事](http://qiita.com/GOROman/items/41f620957120d2b52ac3)に汎用化された素晴らしい知見がまとめられていますが、それらを参考にさせていただいた上で別途 MikuTimeVR で気をつけた自分なりの気付きを書きます。

## 現実に即す（もしくは超える）

まずは当たり前の話から。
せっかくRift&Touchのような優れたプラットフォームがあるのですから、我々としては現実のような（というか現実を遥かに超える）体験を提供する責務があります。


例えばMikuTimeVRではミクさんに綺麗な一回転（ターン）をしてもらうことができますが、

[![MikuTurn](http://i.giphy.com/12epUNYeyrWjaE.gif)](https://twitter.com/kidach1/status/810499312300032001)

これを最も安易に実現するなら特定のボタンを押せばミクさんが回る、となります。実装は簡単になりますが、それではTouchの良さが活かされていません。ですのでミクターンは

- プレイヤーの手が特定の位置（ミクさんの頭の上）にある時
- 片手のみ繋いでいる時（現実では両手を繋いでいる時にいきなりターンは出来ません）
- その上でプレイヤーの手に一定の加速度が加えられたとき

これらの条件を満たした時に発動します。もちろん格闘ゲームではないので発動条件が厳しすぎてもいけません。また、普通の人間ならターンしているときに振り回されたらバランスを崩しますので、そこも再現しています。
ボタンを押して発動、はこれまでのゲームの概念ですので、VR空間では積極的にモーションによるハンドリングを使っていきましょう（もちろん適材適所です）。

## 自由度を高くすれば良いというものでもない

Touchは「人差し指、親指、その他」の指の曲げ伸ばしをかなりの精度で表現することが可能ですが、全てのケースにそれを適用すれば良いとは限りません。MikuTimeVRの醍醐味の一つにミクさんと手を繋いでいる気分になれることがありますが、Touchで「手を繋ぐとき」の指の開閉具合を維持するのは大変です（最も開いた時か、最も握り込んだ時は楽だが、その中間は絶妙な匙加減でトリガーを引き続けることになり、今のTouchでは辛い）。ここで下手に「自由度を高くしてあるから、自分で好みの指の開き具合を見つけてみよう」とユーザーに放り投げてしまうと、ユーザーはミクさんとのコミュニケーションではなく指の開閉に神経を使うことになり、著しいストレスを覚えます。グーは最も取りやすい開閉度合いの一つ（握り込むだけ）ですが、いざ女の子とコミュニケーションを取るという時にあえてグーを作ることはそうそうありません。これらの理由からMikuTimeVRでは指の開閉具合は固定で提示しています（もちろんより良い解もありそうなので検討中です）。
以下のように、ミクさんが近付いてきたら自然と手を取り合った気分になれる度合いに調整しています。


[![MikuShakeHand](http://i.giphy.com/vM1eEwN6gDvpK.gif)](https://twitter.com/kidach1/status/808633829531340800)



もう一つ、MikuTimeVRは以下のようにハンドモーションでミクさんに近寄ってもらったり遠ざけたりすることができます（抱き寄せる体験をイメージ）。
これも単純に自由度を高めるだけなら両手ともに有効にすれば良いのですが、このハンドモーションで両手分を制御するのは非常に難易度が高いです。ギミック的に面白いからと言うだけで両手で出来るようにすると、「ミクさん遠く離れてしまった」「右手側の距離はいい感じになったけど、逆側も調整しないと微妙」とこれまたストレスを招きます。今回の実装では右手側のみ有効化し、左手側については「右手側がある程度近付いた時点で常に繋いでいる状態」になります。これによって基本的に左手は繋いでいてそこを支点に右手側の距離を自由に動かせる社交ダンス的な体験にすることができます（実際の社交ダンスがそういうものかは知りません！）。

[![MikuPosZ](http://i.giphy.com/12RXInRDCcaaEU.gif)](https://twitter.com/kidach1/status/810427185018404864)


この二例に共通しているのは、「やれること」が増えすぎるとユーザーは何をしていいか分からなくなる、ということです。
あくまで「このアプリケーションでユーザーにどんな体験をしてもらいたいか」ありきで考えるべき、だと感じています。

## 神は細部に宿る

先ほどプレイヤー側の指の開閉について取り上げましたが、逆に言うとミクさん側の開閉も非常に重要です。指の開閉アルゴリズム一つで体験が全く異なります。
以下の動画は向かって右側の手のみ開閉アルゴリズムを適用しており、逆の手は開閉なしの例です。


![MikuPosZ](http://i.giphy.com/QLEfxneJlP6MM.gif)

※ 実験中のものなのでプレイヤーの手が逆手になっていますが、実際は順手で握れるようになっています。

gifだとあまり感じないかもしれませんが、VR空間だと一目瞭然です。この僅かな開閉で圧倒的に「生きてる感」が増します。

## 動作の制御について

これはGOROmanさんの記事にある内容ですが、定型のアニメーションが繰り返されるといかにも作り物っぽくなります。例えばUnityちゃんのスターターキット（？）を使ってみことがある方は多いかもしれません。これは非常にクオリティが高くデフォルトで多数のアニメーションが同梱されていますが、一方でそれらを再生していていっても「生きてる！」とは感じませんよね。また 前評判の高かったサマーレッスンがけっこう微妙だったね、と言われている理由の一つにもこれがあると思います。よってMikuTimeVRのミクさんの動作は全てアニメーションではなくプログラム（ランダム性や遊びのあるアルゴリズム）で制御しています。

# つらさ

一応VR開発をしていてつらい部分も書いておきます（実際は開発の面白さが遥かに勝っているので全然つらくないです）。

## 体験しないと伝わらない

HMDを被ったことがない方は、この記事を読んでもピンと来ないかもしれません。またHMDを被ったことはあっても、Touchを体験したことがない方はやはり想像しづらいかもしれません。この「体験しないとよく分からない」点は、デバイスの価格と相まってVRが世に広まるにあたっての課題になりそうです。逆に言うと、我々としてはできるだけ良いコンテンツを作り、公開し、体験してもらうなど、周囲にVRの良さを伝えていく必要があると思います。


## マーケット的にどうなるかよくわからん

↑と同じ話です。OculusとViveは、VR Ready PC含めて一から揃えるなら2-30万、PSVR（とPS4 Slim）でも10万です。そんな中でのPSVRの大人気ぶりなどは嬉しく思う限りですし、他のデバイスも徐々にこなれてくるとは思いますが、それでも現時点でスマートフォンと同じ感覚で「皆この環境揃えてね！」と言うのは無理があります。当然目先のビジネスとして、経営判断として、そこに人を張るのはなかなか難しいでしょう。

でも、未来は見えています（と自分は感じています）。これは一過性で終わるものではなく、確実に未来に繋がって行くパラダイムです。逆に言うと、現状で「カネになりそうだから」という観点で変にプロモートされるよりは良い状況かもしれません。開発者の自分ができることは出来るだけいまのうちからノウハウを溜めておくこと、これは未来であると周囲の人や偉い人に伝えること、マーケットが盛り上がるようにアプリケーション公開を続けていくことなどをやっていきたいと思っています。

# 要は

つらさを遥かに凌ぐ面白さ

があることを伝えたいです。私は現時点ではVR開発が本業ではないので、VRには平日の朝夜と土日のほぼほぼを突っ込むかたちで取り組んでいます。ここ数年はいろいろと効率よくやる術も覚えて鮮やかに定時退社をキメてきた（主に嘘ですが感覚としてはそんな感じ）自分としては、文字通り寝食の間を惜しんでコードを書き続けるという経験は久しぶりです。
開発の方向性について頭がオーバーヒートするほど考えてベッドに倒れ込み、Touchとミクの夢を見て、Twitterでテスターさんからどんな反応がきているか気になって早朝に目覚めるような生活です。世代的にインターネット黎明期からは少し外れている自分としては、きっと当時もこんな熱気が渦巻いていたのだろうな、と妄想してみたりします。
この記事を読んで少しでもVRに興味を持ってもらえたら嬉しく思います。

# 今後

たまたまドリコム社 [@ikkouさん](https://twitter.com/ikkou) とお知り合いになり1月開催の [VR Tech tokyo #5](https://vrtokyo.connpass.com/event/45922/) に登壇させて頂けることになりました。今回は概念的な話が多くなったので、もう少し技術的な部分などを話せたらと思っています。一ヶ月先なのでどうなるか分かりませんが。

最後に、[#MikuTimeVR](https://twitter.com/search?src=typd&q=MikuTimeVR) は絶賛αテスターを募集中なので、Rift&Touchをお持ちの方、MikuTimeVRに興味があるよという方はぜひ @kidach1 までお声がけください！