読者です 読者をやめる 読者になる 読者になる

Unityでよくある10の間違いを避ける方法

https://www.toptal.com/unity-unity3d/top-unity-development-mistakes

こちらを咀嚼した上で自分の体験から書く。

#1 現実を見ようということ。どこよりも綺麗なグラフィックとFPSスマホを超える体験を作ろうとしても、それでは最新のハイエンド端末でしか動かない。Unityで作るとiOSよりAndroidの方がfpsが出ないことが多いので、最新のiPhoneでしか動作確認していないと、モデルを量産した後にどうしようもなくなる。正しい進め方は、リリース日が決まり、その時の最低動作端末が決まり、その最低動作端末で最低限満たしたいfpsが出るようにモデルを作ること。それではテンションが上がらないというのは別の問題としてある。

#2 モデルをImportして使うときにScale = (1, 1, 1)でそのまま使えるように、モデリングソフトとImport時のscale factorで調整する。シーンに置いたモデルのスケールをいじらない。モデルのマテリアルはできるだけ少なく。

#3 Unityはコードに参照を持たせてInspectorで紐づければ簡単に参照できるが、絡み合う構造になりやすいとも言える。どこから状態が変更されたか分からなくなることを防ぐために、状態を変更する役割を誰が持つのか分離する。

#4 基本だが、UpdateでFindしないでStartでキャッシュすること。エフェクトなど何度もInstantiateするものはPoolを使うこと。レンダリングを軽くするためにOcclusion Culling, LODを使い、動的ライトを減らしてベイクすること。Draw Callを減らすためにStatic Batching, Mesh.CombineMeshesでメッシュを合体させるが、このとき合体しすぎてCullingが効かなくならないよう注意する。個別のオブジェクトのマテリアルを共有するためにモデルのTextureをAtlasで共有する。透明テクスチャは避ける。使いたいならalpha blended shaderを使い、alpha test shader, cutout shaderは使わない。シェーダについて、変数の精度を下げたり、複雑な計算はLookup Textureにして負荷を減らす。全体的には、Profiler, Frame Debuggerを使ってボトルネックを見る。Frame Debuggerを使えばマテリアルを分割しすぎて何度もドローしていることなどが発見できる。

#5 Frame RateのスパイクとなってしまうGCを避けること。各フレームで新たなメモリアロケーションをするのは避けるべきであり、コードの書き方で大抵は避けられる。ProfilerでもGC Allocの列で毎フレームAllocateしてしまっているかは確認できる。

#6 100MBを超えるとCellularではダウンロードできなくなりお客を逃してしまうので超えないように収めて、他のリソースはAssetBundleに逃がす。とはいえ、最近は超えちゃってもしかたないと割り切っているアプリ多く見られ、例えばUnityで作られたハースストーンのサイズは2GBである。無駄なリソースが入ってないかは、ビルド後のEditor Logで確認できる。リソースサイズを食うのは主にテクスチャで、圧縮すべきでありTrue Colorはオススメできない。透過のエッジをきれいに見せたい時は、色情報と透過情報を別テクスチャにして色情報の方は圧縮してシェーダで合成し、True Colorよりも軽くする。そのシェーダは有志が公開しているが、UI用のシェーダとしてUnity公式でも出してほしい。

#7 物理エンジンのためにRigidbodyを付けたObjectの動きをコードから操作するときは、Rigidbody.positionやLateUpdate()で状態変化させること。物理エンジンの更新頻度はFixed Timestep setting in Time managerで変更できる。Mesh Colliderは重いので避けたい。物理が重いときはCPU側のボトルネックとなる。

#8 手で動かしてテストすることは徐々に退屈な作業となるし、時間もかかるのでUnit Testで十分な物はそちらでテストする。Play Modeで確認するときの状態設定はボタン1つでできるように自動化しておく。

#9 アセットストアのアセットは万能ではない。プロジェクトと一貫性を持っていることを確認して入れるべきだし、むやみに入れると不要なコードが増えて、コード変更後の再コンパイルに時間がかかるようになる。実装が簡単なら実装した方がコントロールできる。とはいえ例えばTweenなど、実装が簡単でも、アセットとして実績があって最適化もされているコードがあるなら、私はそちらを使った方がいいと思う。

#10 エディタ拡張で開発しやすくする。エディタ拡張は独自の世界があるのでみんなが学ぶべきかという話はあるが、今までツールプログラマだった人が、Unity内でデータを作れるツール作成のためにエディタ拡張を利用するといいと思う。