【Unity5】VRゲーム開発に役立つかもしれないアセットを二つ開発したので紹介と解説
目次
前置き
こちらの記事は Unity 2 Advent Calendar 2016 の17日目記事です。
前回はWheetTweetさんの「Unityのコミュニティ活動でMicrosoft MVPを受賞するには?」でした。
VRゲームを実際に作ってみて感じた個人的難点
以前、私個人でHTC Viveを用いてVRゲームを開発してみたことがあります。
ゲームについてはこちら。
で、実際にVRゲームを作ってみて、個人的に「ここは難点だな」と感じた点がありました。
1. デバッグ
VRゲームを実際に作ってみて、特に不便に感じたのはデバッグでした。
というのも、Unityでは「Debug.Log(出力内容)」で出力させた文字列はUnityエディター内「Console」ウィンドウに表示されるからです。
その為、HMDを付けていては、いつどのタイミングでエラーを吐いたのか、今このタイミング(フレーム)でどのような値になっているのかが瞬時に把握できませんでした。(uGUIで画面内に表示させているなら別)
2. 照準処理
VRゲームやアプリケーションは、私が見聞き、また実際に経験した限りでは、ViveやOculusTouchといったコントローラを使用した銃などで何かを狙い撃ちするゲームでは、点やレーザーポインタが使用されることが多いか、そもそも照準が存在しないようです。しかしこれは「慣れが必要とされ、うまく扱うには多少なりとも時間がかかるな」という風に感じました(あくまで私個人の経験で)。
アセットその1:VRDebugConsole
デバッグに関して、Unity標準のConsole画面と似たようなものを実際のGame画面にも表示したい。そして位置やサイズも自由にさせたいと思い、「VRDebugConsole」なるアセットを開発しました(Collapse切り替えはまだ実装できてません)。
こちら、ウィンドウのスケーリングにも対応しており、ビルボードの設定も行う事が可能となっていますが、まだその程度の機能しかありません。またドラッグの処理もまだ実装できていません。クリック的動作のみ。
下動画は上動画よりちょっと前の開発中の奴ですが、ちゃんとLog,Warning,Errorで表示切替が出来るようになっています。
そのうち座標や回転のバインド処理も追加しようかなと思っています。
後は透明度とか色々設定できるような開閉可能な設定画面とか取り付けられたらいいな。
使ってみる
こちらからアセットをダウンロードできます(今までGithubで管理していなかったので作業途中からのリポジトリ作成で申し訳ないですが...)。
使い方
- Asset/VRDebugConsole内の「VRDebug」プレハブをInspectorないしSceneビューに置きます。
- おしまい
後は、内部で勝手にカメラを取得し、ウィンドウを生成します。
位置が気に入らない場合はSceneビューで大きさを変えたり位置を上下なり左右なり動かして任意の位置にもっていくことが出来ます。
EventSystemに自動追加された「VRDebugInputModule」にポインタとみなすオブジェクトをアタッチすれば、ViveHomeのようなポインタを使用することができ、ウィンドウを操作することができます。
中身の話1:オブジェクトプール
このアセットはオブジェクトプールアルゴリズムを使用しており、ログが高速で増加することによる生成と破棄(増えすぎ防止のため)を極力行わないようにしています。検証は行っていませんが、GCによるスパイクは起きにくくなっているかと思われます。生成の上限数は「VRDebug」プレハブにアタッチされている「VRDebugLogReceiver」コンポーネントから指定できます。
アルゴリズムはこちらにて紹介されていた方法を参考にしました。
中身の話2:Debug.Logの情報を取得する
このアセットは、DebugLogの情報をイベントハンドラに登録して取得しています。
コード全体は以下。
70行目で作成した関数を28行目でハンドラに追加しています。
Application.logMessageReceived += LogCallBackHandler;
イベントハンドラに登録する関数の引数は、「Log(ログ本文)」「StackTrace(ログに関する情報)」「Type(ErrorやWarning等のログのタイプ)」の三つ。
void LogCallBackHandler(string _log, string _stackTrace, LogType _type){
//処理させたい内容
}
後は、取得したログ情報を基に値を渡したりしてやるだけです。
処理についてはこちらの記事を参考にしました。
中身の話3:オリジナルディレクティブ追加によるコンパイル回避
このアセットはViveに限らず使用できるようにしたかったので、SteamVR(OpenVR?)に依存しないような作りにしています(ただしVive環境以外の環境がないので動作検証は行えていませんので動作の保証はできません)。
その為、Viveを接続している場合は任意のコードをコンパイルし、されていない場合はコンパイルしないという仕組みを作るためにディレクティブという仕組みを利用しています。その処理を行っているのが、40~44行目で行っている処理です。
AssetDatabase.FindAssets("t:script SteamVR").Length
でSteamVRアセットが存在するかどうか(インポートされているかどうか)を確認し、存在すれば、「EXSISTENCE_STEAM_VR」ディレクティブを追加します(EXISTENCEの誤字ですいつか修正します)。
UnityではPlayerSettingからオリジナルのディレクティブを追加することが出来ます。
//現在のディレクティブシンボルを取得
PlayerSettings.GetScriptingDefineSymbolsForGroup(ビルドターゲット);
//ディレクティブシンボルを設定
PlayerSettings.SetScriptingDefineSymbolsForGroup(ビルドターゲット, シンボル名);
ディレクティブについてはこちらの記事を参考にしました。
中身の話4:VRコントローラの入力
についてはUnity 2 Advent Calendar 2016 の18日目記事にて公開次第更新します。
書きました。
アセットその2:ConeCollider
照準処理に関して、(個人的に)点やレーザーの何が難しいかって点であるが故に遠くのものを狙いにくく、少しの手のブレで照準が外れてしまうことにありました。というわけで、点やレーザーではなく、「範囲」で対象を取得できるように「ConeCollider」なるアセットを開発しました。
どういうことかというと、Unityに標準で用意されているRayCastやSphereCastでは、距離と感知範囲が比例しないので、遠くなればなるほど、Castの感知範囲はCameraから見て相対的に小さくなります。その為、ConeColliderを作って、疑似的な視界のような円錐型の感知範囲を作ってしまおうという事です。
下動画はAssetStoreに出そうとして投稿したものの一度はじかれてそのままの奴です。
ConeCollider1.0 Samples for Unity3D
動画にもある通り、距離に比例して範囲も広がるので、「ライトの光に当たっているかどうか」だったり、「人の視界に入っているかどうか(MGSみたいな)」を判断するのにも活用することが出来ると思います。
使ってみる
使い方
- 「ConeCollider」コンポーネントを、コライダを付けたいオブジェクトにアタッチします。
- おしまい
後はそのまま再生すればコーン状のコライダが自動生成されます。
設定できる項目は「半径」と「距離」と「トリガー判定」。シーンビューでは円と線で生成される位置や大きさ、回転を確認することができます。
衝突判定は今まで通りのOnCollision~()やOnTrriger~()関数で取得することができます。
中身の話:コライダを生成する
ConeColliderとは言っても、ただ単純に事前にBlenderとかで作っておいた1x1x1サイズのコーンモデルを用意しておき、Unity再生時にAngleやDistanceに合わせてポリゴンを頂点移動させ、MeshColliderをアタッチしているだけです(MeshColliderは非表示にしています)。なので実際に衝突判定を行っているのはMeshColliderになります。
補足
ちなみに、VRDebugConsoleアセットに関して、AssetStoreには
Technie Virtual Console - Asset Store
というものが既にあり、さらに
Unity Advent Calendar 2016 - Qiitaの4日目で紹介されている、凹みさんが作られたWindowsデスクトップ画面を表示するプラグインもあります(あれ、自分のAssetいらない子?)。
宣伝
改めて宣伝です。
今回紹介したアセットを活用して一つ個人でVRゲームを制作してみました。
というより、今回開発したこれら2アセットはこのVRゲーム制作中に同時制作してました。
isemito.hatenablog.comVRだけでなくPCでも遊べます。
また上記ゲーム内ではこちらの自作アセットも活用しています。