テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

Unityで2Dモバイル性能のための46のTips&Tricks(導入・物理演算について)

素晴らしいTips集で翻訳が無かったので訳そうと奮闘して数週間、面倒になったので分かる部分だけ超訳してしまうことにした。

勿論、正確な内容ではないので英語を読めるひとは是非とも原文を読んで欲しい。そして間違った解釈の部分を指摘して欲しい。
(色々な意見を聞いて修正していくのがUnity的って感じですよね ← 言い訳)


また、内容自体も3Gをベースにしているので大分古い内容の所がある。もし「これ納得いかない」等の内容があればコメント欄・Tweet等で話し合いたい。


ちなみに全体のトピックはこんな感じ。

・物理演算について
・スプライトとテクスチャについて
・ロード、セーブとオブジェクトへのアクセスについて
・サウンドについて
・UIについて
・ビルドオプションについて

続きや正しい内容が気になる方は是非とも原文を読もう。

46 Tips & Tricks for 2D mobile Performance in Unity.
http://sicklebrick.com/?p=411



Unityは汎用性とパフォーマンスに優れてるけど、上手く使うには少しコツが必要だね。今回は幾つかTipsを用意したので聞いて欲しいな。

最初の忠告だけど、もし初めてUnityを触るなら「他の言語や開発環境と同様に考えない」事をオススメするよ。例えばUnityのPrefabを使わなかったり、Box2Dを移植しようとしたりとかね。無理にやっても大変なだけだしね。

さて、はじめよう。

物理演算について


内蔵の物理演算を使おう
3Dエンジンの物理演算を2Dゲームを使うのは無駄にみえるかもしれないね。でもPhysXエンジンはUnityのネイティブコアで動いてることを思い出して欲しい。

何より大規模でプロフェッショナルな開発チームにより保守されていて限界まで最適化されているエンジンであって、そこいらの日曜プログラマの2D エンジンとはモノが違う。

ちなみに2Dで動かすにはpositionのz軸とrotationのXとYをfreezeすればいいよ。
スクリーンショット 2013-06-06 0.57.51


1/1スケールを使おう
Unityの単位は1単位1メートルなんだ。この法則を守らないと落下速度や挙動はちょっと妙な感じになるかもしれないから注意が必要だ。

例えば物理の授業で習った重力の法則を思い出してほしい。弾丸とサルの落下速度は同じだと教わったはずだ。だけど実際にゲームの中でスケールを大きくするとスピード感が感じられなかったりするんだ。

勿論、重力を調整したってかまわないけど、そのときは衝突した感じがおかしくなることも覚悟すべきだね。

そうだね、もし小さいスプライトを使いたいなら、カメラの方を拡大するよ良いかな。
スクリーンショット 2013-06-06 0.58.48



質量も正しく設定
スケールだけじゃなくて重量も正しく設定しよう。500kgもある赤ちゃんはいないし、戦車が100gしか無いのもおかしいだろう?


primitive box/sphere colliderはMesh colliderssより高速
当然だけど、円や四角の当たり判定は高速なんだ。必要がなければこっちを採用しよう。


複雑な形状はプリミティブを組み合わせシミュレート
Unityの機能で、親オブジェクトにrigidbodyをアタッチすれば子オブジェクトも含めて1個のコライダーとして扱えるんだ。

これで複雑な形状のオブジェクトの当たり判定も作れるね。
スクリーンショット 2013-06-06 1.00.48



ジョイントでオブジェクトをつなぐ
複数のrigidbodyを組み合わせる場合はジョイントを使うんだ。

車みたいな複雑な形状だって、親オブジェクトで全体を動かせるようにしつつ、その子オブジェクトに様々な組み合わせを使えばいいんだ。
スクリーンショット 2013-06-06 1.03.44


複数のオブジェクトを繋ぐなら間に1個挟む
実はジョイントを1個のゲームオブジェクトに複数配置することは出来ないんだ。でもオブジェクトをつなぎ合わせることでオブジェクトを繋ぐって手もあるね。例えばバネとスライダー、車輪と車軸の間に動かないオブジェクトを挟む・・・とかね。



RigidBodyのないオブジェクトを動かすのはハイコスト
実はrigidbodyの無いオブジェクトは静的なオブジェクトと認識されているみたいなんだ。だからRigidbodyの無いオブジェクトを動かす場合はRigidbodyを加えたほうが良いかもしれないね。


solverIterationCountを定期的に変更した方が良いかもしれない
うーん、これは直感に反するんだけど、solverIterationCountの間隔を一定にしないで定期的に変更したほうが良いパフォーマンスが出る気がするよ。

例えば、負荷が8,4,8,4,8,4になる感じでね。
スクリーンショット 2013-06-09 14.19.31

Physics.solverIterationCount
http://docs-jp.unity3d.com/Documentation/ScriptReference/Physics-solverIterationCount.html

ハイパフォーマンスとローパフォーマンスを定期的に切り替える事で、精度が良くて動作の早い物理演算を目指してる?
議論の余地ありそう

InterpolationとExtrapolationを使用したRigidBodyはお勧めできない
うん、パフォーマンスの観点から使わずに済むのが一番いいね。でも精度を上げるよりはこっちを変更した方が良い結果になることもあるね。 要するにケースバイケースだ。
スクリーンショット 2013-06-06 1.06.16



Timestepを下げる
もしモバイル端末で60FPSを目指すなんて非現実的な事を考えるなら、一番手っ取り早いのがTimestepを下げることかもしれないね。
試しにFixed Timestepを0.05、Maximum Allowed Timestepを0.03くらいの値に設定してみよう。
スクリーンショット 2013-06-06 1.14.44


Timescaleを調整する
タイムスケールは下げれば下げるほど物理演算が雑になるんだ。 逆に高ければ高いほど精度は良くなるけど、処理速度とかを占有されちゃうから注意が必要みたいだね。 高い精度とパフォーマンス、調度良い値を探そう。





次回はスプライトとテクスチャについて。