【VR】【Unity】Oculus Questアプリをビルドする
つつつ、ついに買っちゃいました!
Oculus Quest!!!
PSVRを持っているので、Oculusを買うことは無いかなと思っていたのですが
開発に使うってことで(言い訳?)。
ということで今回は、UnityでOculus Quest用にビルドする方法を備忘録として載せておきます。
- Unityのバージョンを確認する
- Oculus Integrationをインポートする
- Unityプロジェクトの設定を変更する
- Oculus Questを開発者モードに変更する
- ビルドしてOculus Questにapkをインストールする
- 結論
Unityのバージョンを確認する
これ、めっちゃ大事。
ぶっちゃけ自分、これのせいで半日無駄にしました(涙)
上記ページに書かれているのですが、推奨されているUnityのバージョンは以下となっております。
- 2017.4 LTS
- 2018.4 LTS
- 2019.1.2f1
そう、私はちょうどこの時、Unityのバージョンをアップグレードしたばかりだったのです!!(2019.2.0f1)
これのせいで、ビルドが失敗していたものと思われます。
なお、2019.1.2でビルドしたら成功するようになりました。
Oculus Integrationをインポートする
お次に、任意のUnityプロジェクト を作成して、Oculus Integrationをインポートします。そうすると、諸々必要なコンポーネントと共に、たくさんのサンプルシーンもインポートされます。今回はその中から、Assets>Oculus>AampleFramework>Usage>DistanceGrabを開きます。
Unityプロジェクトの設定を変更する
あとはおなじみ、Android向けの設定をプロジェクトに施します。
- Build Settings>platformでAndroidを選択し、Switch Platformボタンを押す
- Player Settings>Company NameとProduct Nameを任意のものに変更します。
- Player Settings>XR SettingsのVirtual Reality Supportedにチェックを入れ、Virtual Reality SDKsの+ボタンからOculusを選択します。
- Player Settings>Other Settings>Identification>Minimum API Levelを19~にする。
- ヒエラルキビュー上のOVRPlayerController>OVR CameraRigのインスペクタで、OVR Manager>Target DevicesのElement 0をQuestに変更する。
- Player Settings>Other Settings>Identification>Package Nameを設定する。
- Player Settings>Other Settings>Rendering>Graphics APIsからVulkanを削除する。これを削除しないと、ビルド時にエラーとなります。
Oculus Questを開発者モードに変更する
Oculus Questを接続したOculusアプリの設定からその他の設定>開発者モードを開き、開発者モードをONにします。その際、団体登録を促されますので、登録しましょう。
次に、Oculus QuestをPC(Windows10)に接続します。Oculus側に接続受け入れ許可を聞くダイアログが表示されますので、許可します。
うまく進まないな?と思ったら、Oculus Questを再起動してみます。私もどこかのタイミングで再起動しました(詳細失念・・・)。
ビルドしてOculus Questにapkをインストールする
Build And Runでも、ビルド後にadb installコマンドでもOKです。前者の場合、自動的に実行されています。後者の場合、Oculusのライブラリ>提供者不明のアプリ内から起動します。
結論
- Windowsは10!Unityは2017.4/2018.4/2019.1.2!これ大事!!(実はWindowsでもハマっていたのは内緒だ)
- Oculusの提供しているアセットがあるので、それを使う
- Oculus Questを開発者モードにする
- HMDをかぶる時は、机の上を片付けよう。特に飲み物類!
↑↑↑ ぜひ遊んでみてください!↑↑↑
【C#】NULL条件演算子について
し、し、知らなかった。
C#6.0以降、null条件演算子なるものがあったってことを・・・。
事の発端
github内のソースを見ていて、ふと目にとまったコードがありました。
こんな風に書かれている箇所がありまして。
これ、なんぞや?と思ってググってみたのです。
まぁ見た感じ、nullチェックなんじゃなかろーかと思って「C# nullチェック」と
検索窓に入れてみたのですよ。
そしたら、
こーんなステキな検索候補が出てくるじゃありませんか!
NULL条件演算子
さっそく「C# nullチェック 演算子」でググッた結果の一番上の記事(安直w)をオープン!そこは私のバイブル「@IT」の記事でした。
よーするに、オブジェクトのメソッドやフィールドにアクセスする際のnullチェックを、「オブジェクト名+?」で簡略化できるよってことらしいです。
今までの書き方@自分
自分、不器用なんで。
今まで、こんな風に書いてました。
これでも間違いではないのです、古い書き方だけど。(三項演算子というらしい)
若かりしころ、こんなコードを書いちゃう自分カッコ良くね?
なんてコッパズカシイことを思っていたものです。
ほんとに若かりしころの話ね。ほんとにほんとね。
ところが@IT様の記事によると、これはスレッドセーフではないと。
val!=nullでnullチェックをした時にはOKだったかもしれないが、ToString()する時点でnullになっているかも知れないと。
そりゃそうだ。むしろとっとと気づけ自分。
それと比較して、null条件演算子はスレッドセーフであるため安全ですし、コードがかなり簡略化できるので非常に使い勝手が良いです。
結論
↑↑↑ ぜひ遊んでみてください!↑↑↑
【Unity】複数の警告を無視する
インスペクタからオブジェクト等をセットする際、public変数にする方法と、privateで[SerializeField]属性をつける方法があります。
私は後者をよく使うのですが(ボッチ開発だけどpublicは使わないw)、スクリプト内で初期値を設定していないとwarningが出るんですよね。
これを踏まえて、警告を制御する方法をご紹介します。
- Unityバージョン:2019.3.0a8
- ランタイム:.NET4.x
[SerializeField]privateするとどうなるか
上図のような警告がコンソールに表示されます。
出ている警告は、CS0649ですね。これは「値が割り当てられていない、初期化されていないプライベート フィールドまたは内部フィールドの宣言が検出されました。」という警告です。
スクリプト内で警告を制御する(C#)
これを消す手段の一つとして、スクリプト内で警告を制御する方法があります。
警告が出ているスクリプトファイル内で、次を宣言します。
ただし、警告が出ているすべてのスクリプトファイル内で宣言する必要があるため、ちょっとめんどくさいですよね。
csc.rspファイルを作る
便利な方法として、Assets/csc.rspファイルを作成し、以下を記述します。
csc.rspとは、defineをグローバルに定義できるファイルのようです。
つまりここに警告無視を宣言しておけば、すべてのスクリプトで参照されるということになります(多分・・・)。
なお、.NET3.5以下を使用している場合はcsc.rspではなく、msc.rspファイルになるようです。
結論
- privateな[SerializeField]は、警告が出る
- 警告を消す方法は、該当ファイルに「pragma・・・」を定義する方法と、Assets/csc.rspに「-nowarn・・・」を定義する方法とがある
- .NET3.5以下の場合、msc.rspを使用する
【Unity】ゴールしたアイテムの色を変える
床に転がっている時、Cubeは緑色をしています。
ゴールした時、赤に変わっていますね。
今回は、この手法についてご紹介します。
マテリアルを作成する
オブジェクトの色は、マテリアルで設定します。
※Physic Materialではありません。ただのMaterialです。
Projectメニュー>Materialを選択し、マテリアルを新規作成します。
色々設定項目がありますが、今回はそのまま!
色だけを設定します。
Albedo項目をクリックするとカラーピッカーが表示されるので、色を指定します。
さらにゴール用にマテリアルをもう一つ作成し、色を赤にします。
スクリプトからマテリアルを変更する
アイテムがゴールしたら、スクリプトからマテリアルを変更します。
アイテムにアタッチされているスクリプトに、以下を追加しましょう。
※新しくスクリプトを作成してアイテムにアタッチしてもOK
実行する前に、上記のスクリプトのインスペクタでゴールマテリアルをセットするのをお忘れなく!
私はよく忘れてUnity様に怒られます・・・。
これで、ゴールしたアイテムの色が変わるようになりました!
結論
【Unity】カメラに映るオブジェクトを制限する
machokoさんゲームで集めるアイテムを、ゲーム画面の左上に表示(案内アイテム:動画内の赤丸部分)しています。
カメラがmachokoさんに合わせて移動しているにも関わらず、案内アイテムはまるでUIのように、同じ位置に同じ大きさで描画され続けています。
今回はこの手法について、ご紹介します。
案内アイテム用のカメラを作成する
案内アイテムは、あたかもUIのように同じ場所に留まって描画したい。
そんな気持ちにこたえるために、案内アイテム専用のカメラを作っちゃいます。
カメラ作成は、ヒエラルキウィンドウ>メニュー>Cameraで作成できます。
案内アイテム用のカメラは、machokoさんに追随する必要はありませんので、SmoothFollowはアタッチしません(メインカメラにはアタッチしている)。
また、カメラを新規作成すると、Audio Listenerがくっついてくるんですね。
これはサウンドを出力するいわばラジカセ(古い・・)みたいなもので。
メインカメラにすでについている場合は、削除しちゃいます。
※複数あると、実行時にコンソールにメッセージが出まくってウザいです。
レイヤを作成する
さて、カメラが複数できたところで、全てのアイテムを全てのカメラで写す必要はないですよね。
そこで活躍するのが、レイヤの概念です。
レイヤとは「階層」の意味を表しています。Photoshopとかにもありますよね。
Unityのレイヤは、カメラのレンダリング対象選別だけでなく、衝突対象の制限などにも使うことができちゃう、優れものです。
案内アイテムのインスペクタの右上に、Layerのドロップダウンがあります。
この最下段の「Add Layer...」を選択すると、Tags & Layers画面が表示されますので、「UI 3D Layer」を追加します。
これでレイヤ作成は完了です。
レイヤを設定する
案内アイテムのインスペクタに戻り、Layerドロップダウンから「UI 3D Layer」を選択します。
これで、案内アイテムのレイヤが設定できました。
メインカメラのレンダリング対象を設定する
メインカメラのインスペクタで、Culling Mask項目を開きます。
これはカメラのレンダリング対象のレイヤを設定できる設定項目です。
ここで、先ほどのUI 3D Layerをレンダリング対象外とします。
※上図では、UIレイヤも対象外としています。
案内アイテム用カメラのレンダリング対象を設定する
案内アイテム用のカメラも同様に、Culling Maskの設定を行います。
レンダリング対象をUI 3D Layerのみとします。
※上図ではUIレイヤも対象としています。
これらの設定で、同一個所に同一サイズで描画される案内アイテムが実現できました!
結論
- シーン内にカメラを複数設置するこができる
- カメラのレンダリング対象は、レイヤで選別できる
- カメラを複数設置することで、いろんな描画ができそう!
【Unity】ゴール判定する
machokoさんが運んだアイテムは、ゴール内の床に接地することでカウントされます。今回はこれについて、ご紹介します。
ゴール床にコライダを追加する
今回はゴール床はPlaneオブジェクトを使っているので、あらかじめコライダがついています。もしついていないオブジェクトを使っている場合のみ、追加してください。
アイテムにコライダを追加する
Cube、Sphere、Cylinder、Coneオブジェクトにもあらかじめコライダがついています。こちらもゴール床と同様、コライダがない場合のみ追加してください。なお、ConeはProBuilderで作成しました。
スクリプトで衝突判定を検知する
コライダで衝突を検知すると、衝突イベントが発生します。イベントを受け取るには、以下のメソッドを必要に応じてオーバーライドします。
- OnCollisionEnter・・・衝突したときに呼ばれる
- OnCollisionExit・・・衝突が終了したときに呼ばれる
なお、コライダのIsTriggerをtrueにしている場合は、OnTriggerEnter/OnTriggerExitを使用します。IsTriggerは衝突を検知するのみで、衝突した結果の物理動作を行わない場合にtrueにします(ぶつかっても跳ね返らないようにしたい場合など)。
衝突した相手の情報を取得し、ゴール床であればゴール判定とするスクリプトをアイテムにアタッチします。
結論
- ゴール判定は衝突判定を使う
- 衝突判定には、コライダを使用する
- ConeオブジェクトはProBuilderで作成できる
- コライダのIsTriggerは、衝突した結果の物理動作を行いたくない場合にtrueにする
【Unity】GameObjectをバウンドさせる
ステージ開始直後、machokoさんが集めるアイテムが空から降ってきます。降ってきたアイテムは、床に落ちるとバウンドしていますね。
今回は、このバウンドについてご紹介します。
Physic Materialを利用する
Physic Materialとは、物理特性マテリアルのことを指しています。これをコライダにアタッチすることで、バウンド等の物理特性を追加することができます。
物理特性マテリアルは、メニューバーから Assets > Create > Physic Material を選択して作成します。
どうでもいいけど、Physicってスペルがなかなか覚えられない。あと、Quaternionも覚えられない。VS使っていれば入力候補が出てくるから問題ないけど、ブログ等で自力でスペルを書かなければいけないときは、調べないと書けないw
あーそうか、入力候補が出てきちゃうから覚えられないのか・・・。
パラメータを調整する
Physic Materialのパラメータには、以下があります。
- Dynamic Friction・・・移動に対する摩擦の大きさ(0~1)
- Static Friction・・・停止に対する摩擦の大きさ(0~1)
- Bounciness・・・バウンドの大きさ(0~1)
- Friction Combine・・・摩擦の計算方法
- Bounce Combine・・・バウンドの計算方法
数値だけで動きを想定するのは難しいので、実際に動かしてみて、いろいろ調整してみるのが良さそうです。今回は、次のように設定しました。
初期値から、Bouncinessしか変えていませんwそれでもなんとなく、うま~い具合に動いてくれちゃうのがUnityのすごいところ!
作成したコイツを、バウンドさせたいアイテムのコライダのMaterialにD&Dすれば完了です!なんてすばらしいw
結論
- 物体をバウンドさせたい時は、Physic Materialを使用する
- Physic Materialのパラメータは、実際に動かしながら調整するのが良い
- VSの入力候補は、人間をダメにする(そんなことはない)
【Unity】シーンをまたいでBGMを鳴らし続ける
machokoさんゲームは、タイトルからエンディングまで、一貫して同じBGMが流れ続けています。
ゲームシーンは①タイトル②チュートリアル③ゲーム④エンディングの4つありますが、同じBGMを途切れさせずに流し続ける方法をご紹介します。
DontDestroyOnLoad指定する
BGMを途絶えさせたくない場合、BGMのAudioSourceを持つGameObjectをシーン切り替え時に削除しなければ良いわけです。
GameObjectを削除しないようにするには、DontDestroyOnLoadメソッドを使用します。
こんな感じに実装してやります。
ところが、これだけだとGameObjectが削除されないために、同じシーンを再度ロードした際にGameObjectがもう1個生成されてしまいます。
static変数を活用する
この現象を避けるために、static変数を利用します。
static変数とは、プログラム内で唯一の実態を持つ変数です。たとえば、staticなフィールドを持つクラスを複数作成したとします。クラスが複数できてもstaticなフィールド自体は実態が1つしか存在しないため、 クラス全員で同じ唯一の値を参照できることになります。
static変数を使って、GameObjectがすでに生成されていた場合に自らを破棄するプログラムを書いてみます。
こうすることで、シーンをまたいでBGMを鳴らし続けることができます。
これはAudioSourceに限らず、シーンをまたいでGameObjectを使用したい場合に有効な手段となります。
結論
- 新しいシーンのロード時にGameObjectを破棄したくない場合、DontDestroyOnLoadを使う
- DontDestroyOnLoadを使う際は、シーン再ロードでGameObjectが増殖しないようにする必要がある
- static変数は、プログラム内で唯一の実態を持つ変数
【Unity】カメラをキャラクターに合わせて動かす
machokoさんの動きに合わせて、カメラが移動しています。これは、StandardAssetsのSmoothFollowスクリプトをカメラにアタッチして実装しています。
SmoothFollowをインポートする
StandartAssetsをダウンロードし、インポートします。全部インポートしても良いのですが、今回はピンポイントでSmoothFollowスクリプトのみとしました。SmoothFollow.csは、Standard Assets->Utility下にあります。
ちなみに一部だけインポートすると、インポートしたアイテムが他のアイテムを参照している場合に参照エラーが起きてしまうので、注意が必要です。
メインカメラにアタッチする
先ほどのSmoothFollow.csをメインカメラにアタッチします。インスペクタのAddComponentボタンでも良いし、ヒエラルキーウィンドウにD&DでもOKです。ちなみに私は後者派です。
パラメータを調整する
メインカメラのインスペクタから、 SmoothFollowのパラメータを調整します。
- Target・・・カメラが追随するターゲットを設定します。
- Distance・・・カメラとTargetとの距離を設定します。
- Height・・・Targetからの高さを設定します。
- Rotation Damping・・・回転速度
- Height Damping・・・上下移動速度
カスタマイズする
machokoさんがゴール中に入ると、カメラが手前に来すぎてしまい、ステージが見切れてしまう現象が起きました。
これを防ぐために、SmoothFollow.csを少しだけカスタマイズ。
SmoothFollow.csでは、LateUpdateメソッド内でカメラ位置を調整しています。これを、以下のように修正しました。
結論
- カメラでターゲットを追随するには、StandardAssetsのSmoothFollowを使うと便利
- インポートしたスクリプトは、自分好みにカスタマイズしよう
- アセットは、使うもののみインポートすることができるが、参照エラーが出る場合があるので要注意
【Unity】キャラクターにUnityちゃんのモーションをさせる
マッチョのmachokoさんにかわいらしいモーションをつけるため、Unityちゃんのモーションデータをお借りすることにしました。今回は、その手順をご紹介します。
※UnityちゃんのAsset利用規約に「キャラクターのイメージを著しく損なわないこと」とあって、これに抵触しないか非常に不安ですが(汗
- machokoさんのデータをインポートする
- Unityちゃんアセットをインポートする
- Animator Controllerを作る
- Animator ControllerのStateにモーションを割り当てる
- Stateを遷移させる
- 結論
machokoさんのデータをインポートする
まずはメインキャラクターであるmachokoさんのデータをAssetストアよりダウンロード&インポートし、prefabフォルダからDimples.prefabをシーンビューにD&Dします。
TTポーズ・・・いや、Tポーズのmachokoさんがシーンビューに現れました。
これだけじゃ全くかわいくないですね。
machokoさんのかわいらしさが全く出ていません。(2回言った)
Unityちゃんアセットをインポートする
お次に、みんなのアイドルUnityちゃんアセットをダウンロード&インポートします。
もし過去にダウンロードしたことがある場合、Assets->Import Package->Custom Package...から直接インポートすることもできます。
なお、アセットストアからダウンロードしたパッケージファイルはAppData\Roaming\Unity\Asset Store-5.xに保存されています。
このパスを変えたい場合、下記サイト様にて紹介されている方法で実現することができるようです。
Animator Controllerを作る
プロジェクトビュー->Create->Animator Controllerを選択し、Animator Controllerを作成します。作成したControllerは、machokoさんのインスペクタのAnimatorにD&Dします。これで、machokoさんのモーションを制御できるようになりました。
作成したAnimator Controllerを選択した状態で、Windowメニュー->Animation->Animatorを選択し、Animatorウィンドウを表示します。
上のステートマシンが、実際に作成したmachokoさんモーション用です。
machokoさんのかわいらしさを全面的にアピールするため、idleモーションを多数用意しましたw
Animator Controllerの使い方は、いずれ別途記事にしたいと思っています。
Animator ControllerのStateにモーションを割り当てる
machokoさんのモーションは、
- アイドル
- 走る
- ゴール
上記3パターンとなっています。アイドルに関しては、かわいらしさをアピールするため(3回目)4パターンのモーションを入れています。
それぞれのステートをAnimatorウィンドウで選択し、インスペクタのMotionの横のボタンを押下すると、選択できるモーションが一覧表示されます。
Unityちゃんアセットをインポートしていれば、Unityちゃんのモーションがここに表示されるので、お好きなモーションを選ぶことができます。
Stateを遷移させる
Stateを遷移させるため、Animatorウィンドウ上でパラメータを作成します。
- idlePattern (アイドル用):int型(0~4)
- isRunning(走る用):bool型
- isGoal(ゴール用):bool型
アイドル状態は4パターンですので、スクリプトから1~4の値をランダムにセットしています。0になったら、アイドル状態を終了します。
machokoさんはWASDキー操作で移動するので、これらのキーが操作された際にidlePattern=0,isRunning=trueにセットします。
お題を達成できたらisGoal=trueにすれば、ゴールアクションしてくれます。
結論
- Animator Controllerを使用し、キャラクタの状態に沿ってモーションを定義できる。
- Unityちゃんアセットをインポートすると、モーションが選択できるようになる。
【Unity】unity1weekに参加しました!
unityroomの1weekゲームジャムに参加しました!
★タイトル:Run machoko Run
★URL:https://unityroom.com/games/run-machoko-run
★プレイ動画はこんな感じ
unity1weekゲームジャムとは、お題に沿ったゲームを1週間で作り上げて
投稿しよう!というコンテンツです。
今回のお題は「あつめる」でした。
私は参加2回目ということで、前回(というか、今まで)実装したことのない
キャラクターのモーションを入れることを自らのお題にしてみました。
マッチョのmachokoさんが、走り回って指定アイテムをゴールまで運ぶ・・・
と言うゲームです。
タイトルは、「Run Lola Run」という映画をインスパイアしました。
※え、古い?古すぎる?年代がばれる?昨今の若者は知らんだろう??
ほんとは、「TT筋肉体操」(machokoさんがTポーズで走るから)とか
「TTマッチョラン」とか、はやりに乗っかろうと思ったのですが
つい昔すぎる映画のタイトルに乗っかってしまいました・・・。
machokoゲームを実装するにあたり、使ったテク等をブログにまとめていこうと思います。技術ブログというか、備忘録も兼ねて。
もしお目に留まったなら、machokoゲームも遊んでいただけると嬉しいです。
「あー、ここでこーゆーことやってるのね」とか
「こーゆーやり方があるのか」など、実際の動きを見る方が理解しやすいと思うので。
次回以降、記事にしていきます!
リリースアプリのプライバシーポリシーについて
プライバシーポリシー
本プライバシーポリシーは、ヒナタ製作所が提供するアプリケーション(以下、本アプリ)における利用者情報の収集および取り扱いについて、説明するものです。
本プライバシーポリシーの内容をよくご確認の上、本アプリをご利用いただけますようお願いいたします。
利用者情報の収集および利用目的
広告配信
本アプリでは、広告配信のために「Unity Ads」を利用しています。
「Unity Ads」とは、Unity Technologies社によって提供されている広告配信ツールです。
利用状況解析
本アプリでは、利用状況解析のために「Unity Analytics」を利用しています。
「Unity Analytics」とは、Unity Technologies社によって提供されている統計データ取得ツールです。
Unity Technologies社の公開しているプライバシーポリシーについては、以下のサイトをご確認ください。
収集情報の取り扱い
収集した情報については、サービス改善や利用に関する動向調査等に利用させていただきます。
原則として、第三者へ提供することはございません。
プライバシーポリシーの変更
本プライバシーポリシーは、アプリのバージョンアップや事業内容の変更等により変更される場合があります。
お問い合わせ
本プライバシーポリシーに関するお問い合わせは、以下のメールアドレスにて受け付けております。
atelierhinata77@gmail.com
ヒナタ製作所について
はじめまして
SE暦20年のしっぽです。
2019年5月より、フリーランスエンジニアとして活動を始めました。
受託案件の隙間で個人ゲーム(Unity)を製作しています。
※現在は仕事量が逆転しておりますが・・・(汗
経歴
製造会社のソフトウェア部門に20年所属。
その間、C++、C#、JavaでBtoB向けデスクトップアプリを開発。
要件定義~テストまで、幅広く経験。
メンバー管理を行いつつ開発も担当する、ブレイングマネージャー(モドキ)。
案件
ヒナタ製作所は、将来的にインタラクティブなコンテンツの配信を目指しています。
現在はUnityでゲーム作成を主としておりますが
Unityを使った受託案件も募集しております。
Unityエンジニアとしては、まだまだ駆け出しではありますが
何卒よろしくお願いいたします!!
今後
グラフィックデザイナーが参戦するやも・・・!?