きかいや。

機械といいつつだいたいプログラミングのはなし

PCVRからモバイルVRへの移植と最適化

日曜趣味プログラマみたいなものなので、
ガチのゲーム系開発者じゃない私が、PCパワーにあかせて動かしていたVRフライトシミュレータを
MirageSoloとかOculusQuestに移植するときに知ったこととかを書いていくメモです。

いきなり落ちる

このレベルだと実機ではプロファイラも使えないので、以下の方策を取る。
まずメモリの使い過ぎを疑う。
・PC向けビルドでもいいので、MemoryProfilerを見る。
・MSAAとかはアホみたい(数百MBとか)にメモリを食うのでまずは切る。
・Resousesの中身が膨れ上がっていないか?捨てて。
・AssetStoreで買ってきたモデルがやたらテクスチャリッチじゃないですか?解像度を下げる。
 解像度の高いテクスチャは片っ端から解像度を下げて、気になるやつだけ解像度を上げていったほうがいい。
・ビルドに含まれるファイルのサイズを調べて、要らなそうなのを捨てる
・Bakeしたシャドウも重い

動くようになってから

ガクガクでクソ重い場合

・Profilerを見てどこに食われているかを見る(実機が良い)
-Renderなら描画系(だいたいテクスチャがデカい。UIも意外とクソ重い)
 -Vsyncに食われてたらGPUが間に合ってない
 -Physycsに食われてたらColliderやFIxedUpdateの中身
 -Scriptに食われてたら個々のスクリプト見るしかない
・MemoryProfilerを見てどこが食ってるかを調べる
・LODはそのぶんモデルが増えるからメモリには優しくない。
切り替え判定も重いので意外とボトルネックになる…
・GPUInstanceingはGPUが間に合わなくなってボトルネックになることがあるので、
CPUに任せるかGPUに任せるかは線引きが必要。
・カリングも視界に入るかどうか?の判定処理が意外に重いので、切ったほうがいいこともある。
・PCでは気にならなかった物理のあたり判定がやたら重い。
 無駄なColliderを減らしたり、Layerを分けて干渉しないものの設定をして、あたり判定処理の回数を減らす
・フレームデバッガ―を見て、主にマテリアルを減らせ。
・仮置きした3DObjectがやたらある場合、メッシュをまとめろ

シーンロードで落ちる場合

・メモリがギリギリだと、シーン選択のシーンのメモリを保持してる余裕がない。
単体シーンを読み込むとなんとか起動するんだけど、
シーン選択画面からシーン遷移してくると落ちるんですよね。
LoadScene直後は両方のリソースを保持してるので限界超えて死んでること多い。

シーン遷移時は
1.選択画面からは空のダミーシーンを読み込んで、
2.シーン選択画面のリソースを破棄して、
次の重いシーンを読み込んで
という段階を踏むとメモリが割とあいた状態になるので何とかなったりする。

人力飛行機 シミュレータ HPASim のはなし

Google人力飛行機 シミュレータ」で検索したらHPASimが全然引っかからなかったのでショックを受けた…

ここでダウンロードできます。
drive.google.com

特徴としては
VR対応(なくても遊べます)
・各種コントローラ設定可能(デフォルトだとXInput系かPS4コン)
・TFで使いそうなマップをいくつか選択可能(富士川とか琵琶湖とか…)
・SRTM30による地形作成/国土地理院の航空写真データによるテクスチャ作成によるそれなりのマップのそれらしさ
です。

琵琶湖モード
youtu.be

富士川モード
youtu.be




記事をマメに更新したりしないとダメですね。

android(OculusGOとかMirageSoloとか)向けUnity設定メモ(コントローラとかうごかないんですけどー

UnityでAndoroid向けビルドが通るようになり、
OculusGOやMirageSoloのためのアプリビルドが通るようになりました。

で。XBOX OneコントローラとOculusGOがつながって、
さあHPASim移植完!
ゲームプレイ!って思ったんですけど、左スティックとスティック押し込み以外認識してくれなくて
変だなー、おかしいなー、と思ってたんですけど、
そういえばUnity野郎、
同じコントローラなのにOS変えるとコントローラの挙動が違うっていうかー、
そういう話がMac/Windows間でありましたね
ええ…そこをどうにかしてくれるのがミドルウェアじゃないの…?

あったあった、やっぱり…
Xbox360Controller - Unify Community Wiki
あ。。。でもandroid向けの設定書かれてないや…

とか言っててもダメなので仕方なくコントローラ設定を作ります。

この辺を参考に…
nn-hokuson.hatenablog.com
assetstore.unity.com
ビルドしたアプリをインストールして
・OculusGO上でのXBOX Oneコントローラの挙動
を確認したところ
以下のようになりました。

ご参考に。(OculusGO/MirageSoloともに同じでした。まあOS一緒ですしね)
f:id:machinemaker:20180519191843p:plainf:id:machinemaker:20180519191846p:plain
ビルドしたアプリはここに置いておきます。(上のアセットをVR対応しただけ
https://1drv.ms/u/s!AjVG1H_FjAPag8xujzFsffu9f9WzKA

                                          • -

しかしこのプロジェクト、
[HMD環境]
・Win+OculusCV1
・Win+HTC Vive
・OculusGO
・MirageSolo
[コントローラ]
XBOX One コントローラ
・(あわよくばPS4コントローラ)

の環境で動くことを目標としているので、OVRInput使うのはなあ…(使ってもHTCViveで動いたり…しませんよね…?
うーん、Rewired買ってしまおうか…
[以下随時更新]

HPASimのフライトモデルと計算課程

HPASimは有限要素法に近い運動シミュレーションを行っている。
フライトシミュレータのモデル作成は基本的に実機の設計値をひたすらプログラムのパラメータに落とし込むことになる。

0.前提:飛行機を部分ごとに分割して表現している.

現状HPASimの翡翠(09年 TBW機)では

プロペラ
胴体、フェアリングパイロット、
主翼中央、左右第一翼~第四翼(第四翼がオールムービングエルロン)
ラダー左右、エレベータ
の16要素で表現している。

これらに対して重力、推力、揚力、抗力の計算を行う。
※その後ひたすら足しあわせて力とモーメントを行っている。
その後加速度・角加速度計算→積分→速度→積分→位置
の計算.
(※以降はUnityでは物理エンジンがやってくれる。
DXライブラリ版ではそこも自前計算)


1.パラメータ入力:それぞれの要素の中身を入れる
各要素は
・翼型:迎角αに対するcd/cl/cmのリスト
・上反角:
・質量:
・翼面積:
・取り付け迎角:
・要素の位置(原点は設計時の適当な基準):
※プロペラ(エンジン)だけは回転数と速度に対する推力のリストや関数を持っている。

を設定する。
ユーザはこのパラメータを入れてやることになる。

パイロットを胴体やフェアリングと別に設定したのには意味がある。
パイロットの体の動きによる重心・慣性変化を再現するつもりで組んだからだ。

※胴体はcl=0としてcdのみ入れている。
パイロットはcl=cd=cm=0,質量50kgのように、質量のみ入れている形。
垂直尾翼は上反角90度として表現する
フェアリング垂直尾翼と同様の表現
※現バージョンではcmは入れてあるが計算は無視している(面倒だったから)
※現バージョンではプロペラは回転数に対して線形に推力を出させている
(速度依存無視、回転速の3乗比例ですらないなんてひどい雑さだ!)
パイロットは重量要素として大きいので、飛行機とは別にRigidBodyを用意してJointしたほうが適切な表現かもしれない。



FSMSなどの通常のフライトシミュレータの場合、
各要素ではなく全機としてのCL/CD/CM、重量、慣性モーメントなどをいきなりぶち込むことになるはず。
操作してみて特性を調整するにはそちらのほうがあっているかもしれない。

ーーーー------------------------------ーーーー
ユーザ側での設定は終了。

以下、シミュレーションの過程

                              • ーーーーー

2.重心位置、合計重量、重心周りの慣性モーメントを計算する。
加速度計算の前準備
2での入力値をもとに自動計算するようになっている。
回転計算用に、計算用に機体座標系で、重心位置が原点になるように座標系の取り直しをしている。
現在のところこの計算は初期化時に1回のみ行っているが、
パイロットの体重移動などを反映するなら毎フレーム計算するか、
RigidBodyを機体とパイロットの二つに分けたほうが良い。


3.各要素の翼面の法線ベクトルを計算する
迎角計算の前準備。

4.迎角を計算する
翼面の法線ベクトルと要素の相対速度(対気)(風の影響、機体の姿勢回転による影響も含む)のベクトルの内積から迎角を計算

5.揚抗力を計算する

6.揚抗力・推力・重力をRigidbodyに加える

7.加速度以降の計算は物理エンジンが行う。

8.あたり判定処理はUnityのColliderを使う

9.アニメーション、SEなどはUnityの機能をお好みで。

Unity5.5でLumenWorksのDLLがエラー吐いたんでメモ

Unity5.4->5.5にアップデートしたんですが、エラー出たんでメモ。
CSVの読み込み用に、
LumenWorksのCSVReaderGitHub - phatcher/CsvReader: Extended version of Sebastian Lorien's fast CSV Reader使ってたんですが、

error CS0012: The type `System.Data.IDataReader' is defined in an assembly that is not referenced. Consider adding a reference to assembly `System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

とかエラー出ました
調べてみるとなぜかSystem.Data.dllへの参照が亡くなってるみたいなんで、
http://answers.unity3d.com/questions/965867/cant-find-systemdata.html
この辺を参考に、
Unity\Editor\Data\Mono\lib\mono\2.0
にあったSystem.Data.dllをAsset下にぶち込んだら解決しました。

なんで消えたんだ・・・。

EntryPointNotFoundException

背景:Unity用にC++のDLL作ってたんだけど

課題:EntryPointNotFoundExceptionでハマったのでメモ。

原因:C++側のcppファイルには実装してるのに
ヘッダファイルで宣言忘れてたってオチでした。

言い訳:ヘッダファイルとかリネーム機能なしエディタが久しぶりすぎて脳が退化している…