Unity:物理 回転 クォータニオン

今回は結構むずい クォータニオンの話です。

 

Unity:物理 回転

オブジェクトをくるくる回してみます。

インスペクターから回転速度を調整できるようにpublic としてspeedを定義します。

ステップはconst で定義しておきます。

左クリックを検出するために if (Input.GetMouseButton(0))します。

今回はUnity標準のrigidbodyを使わせていただきます。

角速度はアトリビュートangularVelocityに格納されているのでこれをいじります。

 

Unity:物理 自由落下

今日は、Unityを使って簡単な物理計算をやってみようと思います。

跳ねるボールを作ってみます。

Unity上で球を上空へ配置した状態で、下記のスクリプトをアタッチします。

ゲットコンポーネントしますがUnityのrigidbodyは使用せずにMyRigidbodyというスクリプトを自分で定義します。

MyRigidbodyの中では加速度 速度 位置について時間ごとの計算を行います。

後に次のスクリプトでAddForceメソドを定義しますが、これで任意の方向に力を加えることができます。ここでは重力加速度になるようにy = -9.8としました。

通常のrigidbodyでgravityを定義できますが、今回はなるべく自分で定義していくことをコンセプトとしています。

球にアタッチする2つ目のスクリプトとしてMyRigidbodyを定義します。

加速度 速度 位置の変数をVector3型で用意します。

ステップ幅を1/60sとします。ここを1/600とすると 1/10スローモーションとして演算できます。

初期化のところでは、オブジェクトのtrasform.positionを取得するだけです。

AddForceメソドをpublicとして定義します。1つ目のスクリプトで読み込めるようにするためです。

で、引数として forceを入れます。さっきのVector3 (0f,-9.8f,0f)ですね。

このforceはaccelerationに加算されます。初期ステップ目では -9.8m/s2ということです。

1ステップ更新すると、このaccelerationに対して時間dt=1/60s を掛け算した値であるvelocityが計算され、さらにそのvelocityに時間dtを掛け算した変位(1ステップの移動量)positionが計算されます。

これでpositionはどんどん下がっていくので、床と衝突します。

衝突は、オブジェクトの中心座標分だけ床から浮いた状態を床との接触状態と考えてif文で検知したら速度を反転させ跳ね返るようにします。

最後にaccelerrationはゼロに初期化して、次のステップで再定義されるための準備をします。

 

VR:はじめてのOculus quest 開発

こんにちは Keita_Nakamori(´・ω・`)です。

ついに始まりましたOculus quest 開発。やっていきましょう。

開発者モードにする

  1. まずは、Mirage Solo でもやったように、開発者モードに切り替えます。
  2. Oculus の初期セットアップのときにスマホへOculusアプリをインストールしているはずですので、起動しましょう。
  3. スマホ右上の設定ボタンをおして、近くにあるOculus Quest xxxxxxxxxxx がアクティブになっているのでタップすると接続済みになります。
  4. 近くにあるOculus Quest xxxxxxxxxxx>その他の設定>開発者モード をタップしましょう。
  5. スマートフォンにインストールされたOculus アプリからOculus Questの開発者モードを許可します。
  6. このとき、組織名を登録しなくてはなりません。NDAがどうたらとか確認ボタンを押してください。組織名はカッコいい名前をつけてください。管理者とか開発者の名前も登録できるようですが、よくわからないので無視しました。OKボタンとか確認ボタンもないので普通にスルーです。
  7. その後PCとOculus Questを接続すると、Oculus Quest側にUSB接続を許可しますか、というメニューが出るので、OKしましょう。
  8. これでPCからOculus Questのライブラリフォルダにアクセスができるようになりますのでアプリのインストールファイルであるapkファイルをこのルートで設置することができます。が私はやりません!!

Buid and Run してみる

  1. Mirage Solo 用のUnity Project があったので、Oculus Quest用に改造します。
  2. Unityを起動してAssetsStoreからOculus Integrationをダウンロードしインポートします。終わったらなぜかUnity がRestartしました・・・。
  3. Project内にあるAssets/Oculus/VR/Prefabsの中にあるOVRCameraRigをHierarchyに追加し、Main Cameraを削除しておきます。
  4. OVRCameraRigにアタッチされたOVR ManagerのTargetDevicesをQuestに変更します。
  5. ProjectSettingsのPlayerの設定でMinimum API LevelをAndroid4.4(API level 19)に設定します。
  6. ビルドはFaceBookではなくてAndriodのままでOKです
  7. ではBuid and runしてみましょう。

さあ、Oculus Questを覗いてみてください。ひとまず見るだけはできる状態になっているはずです。

 

VR:Mirage Solo で視界共有(画像出力)

えー、Keita_Nakamori(´・ω・)です。

Mirage Solo の画像をみんなで共有するために外部のディスプレイやプロジェクタへ出力する方法を調べてみました。

Chrome Castを使えば出来る

Chromecast 3 または Chome Cast Ultra という、スマホの画面をテレビに無線でミラーリングするデバイスがありまして、これをテレビのHDMI入力に挿して、スマホからWifiで映像を送るというものだそうです。

Amazonで2000円前後のものがありますが、それは最新のものではありませんので注意です。

Mirage Soloも中身がほぼスマホですから使えるというわけであります。

Mirage Solo ディスります

しかし、現在ではスタンドアロンで6DOFといえば、Mirage Soloの独壇場ではありません。Oculous questがすでに発売されており、コントローラーやSDK、ソフトウェアタイトルなど、Mirage Soloは過去の産物となりつつあります。

Mirage Soloもそれに対抗するために開発者向けのキットとして、新しいコントローラーを出していますが、一般に手に入るのはいつになるかわかりませんので絶望しかありません。

よって、今後はVR開発をOculous questでやっていくことにしました。

Oculous quest の画像出力

Oculous quest の画像出力に関しては、scrcpyを使う方法があります。

https://qiita.com/Tomoyuki_Mikami/items/183be9b0698ee00f7fac

https://github.com/Genymobile/scrcpy

または、こちらもChrome Castが使えますので、お好みでどうぞ。

今後のOculous quest VR開発 で参考にしたいサイト

では、今後Oculous Questで VR開発を継続していきます。

Oculus Quest向けアプリの個人開発は可能か? 実機で確かめてみた

 

アリーヴェ デルチ。(´・ω・)

VR:シーンをAppボタンでリセットする

モジュールUnityEngine.SceneManagementを使ってシーンをリセットしてみます。

ごみオブジェクトが溜まりすぎたときは一気に消去できて便利です。

DayDreamコントローラーのAppボタンが押されたとき、シーンがロードされます。

GvrControllerInput.AppButtonDownとSceneManager.LoadScene(0)を使っています。

スクリプト(Reset.cs)

これを、ヒエラルキーのどこでもいいのでCreate Empty してAdd Component>Reset.cs を指定すれば、当該スクリプトが発動します。

以上でございます。(´・ω・`)

VR:オブジェクトの重力落下、衝突、再実体化、破壊

こんにちは、Keita_Nakamori(´・ω・`)です。

今日は、オブジェクトの重力落下、衝突、最実体化、破壊までをやってみましたのでメモっておきます。

モデルの作成

まずはモデルの作成ですが、滑り台とシュートを作っていきました。

それぞれ、Create Emptyし、その中に部品を配置し一つの塊にしました。

その際、今回のモデルは斜面なので、なるべく簡単に調整できるよう、一旦、水平に作成したものをプレハブ化してPrefabsフォルダに保存し、ヒエラルキーへ呼び出したあとに、Rotationで斜面にするというやり方を採用しました。

さらに、後ほど再実体化(Instantiate)するときの出現位置を設定するために、予めプレハブ構成の中に、出現位置としてオブジェクトをひとつ配置しておくことで、指定が簡単になるメリットがありました。(結構重要)

 

重力落下と衝突面の定義

重力の定義は、オブジェクトに対してAdd Component>rigid body でUse GravityをONにすれば重力1Gが定義されます。

  • 質量Mass=0.01kg
  • 進行方向抵抗Drag=0
  • 回転抵抗Angler Drag=0

としました。

衝突面の定義は、オブジェクトに対してAdd Component>Mesh Collider で定義できます。注意ですがここでIs Triggerにチャックを入れてはダメです。これは接触を検知したら別のスクリプトを走らせるためのものなので、逆に接触しなくなります。(非常にわかりにくい。)

MeterialへはPysicalMaterialとして予め作成したPM010を定義しました。

再実体化(Instatiate)

オブジェクトを再出現させるところをやっていきます。

Crate EmptyでGameControllerという名前にして、そこにAdd Componentで再出現スクリプト(Summon.cs)をアタッチする作戦で行きます。

スクリプト(Summon.cs)

DayDreamコントローラーのメインボタンを押すと発動するように作成しました。

GameControllerのインスペクター

スクリプトのおかげで、Summon ObjectとSummon Positionをインスペクターから定義できるようになっているはずです。

Summon Objectには出現位置として使用し、InstatiateするオブジェクトをAssetsのPrefabからドラッグします。ヒエラルキーから持ってくるとうまく再実体化できませんでした。

Summon Psition にはプレハブモデルの中にひとつだけ搬送ワークを設置していますので、それをヒエラルキーからアタッチして座標を取得します。

やってみましょう

ここで問題発生です。オブジェクトが増えるとFPSが極端に下がってしまいます。

オブジェクトの破壊

出現から一定時間後に自動的に破壊されるようにスクリプトを追加します。

スクリプト(TimeLimitObj.cs)

 

オブジェクト自身にインスペクターからAdd Component>TimeLimitObj をアタッチして、Life_timeに例として60(秒)などと入力します。

結果、60秒後には全てのオブジェクトが消滅します。

次回の課題

VR(Mirage Solo)の視界を他者も共有できるようにしたい。

まともな人間のアセットを配置したい・・・

 

MR:mirage solo のパススルー機能を使ってみた

どーもこんにちは、Keita_Nakamori@(´・ω・`)です。

捨てようかどうか迷っているMirage Soloについて、最後にMRをやってみようと思います。

環境

  • Windows10 home
  • Unity 2018.4.4f1
  • GoogleVRForUnity_1.200.0

ヒエラルキー

  • GvrBetaHeadset:新しいです
  • GvrControllerMain
  • GvrEventSystem
  • GvrEditorEmulator
  • GvrBetaControllerPointer:これも新しいです
  • PlayerというEmptyを作って、その中にMain CameraとGvrBetaControllerPointerwを入れておきます。

GvrBetaHeadsetの設定

起動と同時にMRが発動するように、インスペクターでGvrBetaHeadsetスクリプトのグルーバル変数であるInitial Camera Mode を Tone Mapに、Initial Scene TypeをAugmentedに変更します。

カメラの設定とオブジェクト配置

カメラの背景はHolo Lenseと同じく完全透明のSolid color (0,0,0,0)への変更が必要です。

カメラの座標はカメラの親であるPlayerでy=1.5にします。カメラ自体は(0,0,0)です

オブジェクトは1m角の枠とユニティちゃんを配しました。

ではビルドしましょう。やりかたはVRのときと全く同じです。

MRとVR(オブジェクトだけ)を切り替えたいとき

下記サイトを参考に、スクリプトをPlayerに貼り付けます。これで、Appボタンを押せば切り替えられるようになりました。

【Unity(C#)】MirageSoloのシースルーモード導入方法

スクリーンショットを貼っておきます(Volume Down ボタン+ DayDreamボタン(一番下))

スクリプト

念の為、置いておきます。

ViewModeChange.cs

弱点

オブジェクトの前になにも障害物がない状態では問題ないのですが、例えば、手をユニティちゃんの手前にかざすと、隠れるはずのユニティちゃんが隠れてくれません。

ここがホロレンズと違うところで、手はオブジェクトとして認識されているわけではありません。

よって、手はパススルーの背景と同じ扱いをされてしまいますので、手で遮っても、その上にユニティちゃん(オブジェクト)が乗ってくることになります。

このときに盛大な違和感を憶えます。

でも、手をオブジェクトの後ろに回すぶんにはなんの違和感もありませんし、むしろ自然な感じが良いです。

今後

  • パススルー画像をリアルタイムで解析して、
  • 手の動きをオブジェクト化し、
  • ユニティちゃんの手前にかざし、ユニティちゃんが見えなくなるような方法を探る。

そんなことができるでしょうか。

VR:Unity空間内をDayDreamコントローラーで歩く5(できました!)

今日は、キーボードからではなくて、デイドリームコントローラーからの入力を受け取るように改造していきます(´・ω・)

かなり前にSummonFunc()を作ったときにやったのを思い出しながらやってみます。

条件式:if (GvrControllerInput.ClickButtonDown) でコントローラーのボタンがクリックされたことを認識したときに、関数SummonFunc()を実行しています。

関数SummonFunc()は任意のオブジェクトを任意の座標と向きを定義してヒエラルキーに追加(Instantiate)する内容になっています。

変更しましょう:

Gvrのメソドを利用していきましょう。

GvrControllerInput.以下のメソド

  1. AppButtonDown     : アプリケーションボタンを押したとき
  2. HomeButtonDown : ホームボタンを押したとき
  3. ClickButtonDown   : タッチパッドボタンを押したとき
  4. TouchDown               : タッチパッドに触れたとき
  5. TouchPos                    : タッチパッドに触れている位置(Vector2)

if(GvrControllerInput.TouchDown)

  • tpX=0.5,tpY=0.5が中心で
  • 前進はtpY<0.3のときにしよう
  • 後退はtpY>0.7のときにしよう
  • 右を向くのはtpX>0.7のときにしよう
  • 左を向くのはtpX<0.3のときにしよう

もっといい方法があるかもしれないが、まずはこれでやってみよう。

スクリプト:PlayerMover2.cs

デイドリームコントローラーで動きました(´・ω・)

まだまだ、改良は必要ですが、とりあえず動くものはできました。

かれこれ、2日まるまるかかってしまいましたが、大きな前進です!

起動直後になぜか、カメラが動いてしまいます。

後日調整が必要です。

VR:Unity空間内をDayDreamコントローラーで歩く4(まずはキーボードから)

前回は結局 ロコモーションもスクリプトがおかしいですよーと警告が出てどうにもなりませんでした。しかも、ロコモーションアセットを全部消しても、ビルドができなくなるというわけわからん状態になったので、プロジェクトを捨てました。恐ろしいです。ここいらでちゃんとUnity勉強したほうがいいかもしれませんね。

基本に立ち返って、自分でカメラ操作のスクリプトを実装していこうと決意した次第であります。

今回の成果:大きな前進(*´﹃`*)

キーボードのWASDまたは矢印キーでプレイヤー視点を移動することに成功しました。

スクリプト:PlayerMover.cs

動いた、嬉しい。