Unityにおける最適化、高速化まとめ

Unity最適化、高速化まとめ_アイキャッチ
目次

はじめに

Unityで動作が安定しないとき皆さんはどうしているでしょうか?今回は比較的簡単に動作を見直す方法をまとめてみました。

プロファイラを見て何が原因かを調べる

まず何が原因で動作が重いのかを見つけなければいけません。そのためにまずはUnityのプロファイラを見て原因を見つけましょう。

プロファイラはWindow→アナリティクス→プロファイラで開くことができます。

プロファイラ

プロファイラがRecordされている(PlayModeの隣の◯が赤色)状態で実行すると上のような感じになります。

上の状態だとCPUUsageの真ん中あたりが大きく乱れています。この場合なにかしら処理負荷がかかっているので原因を特定して改善してあげると動作が安定します。これを見て描画系が原因なのか、RigidBodyやスクリプトC#などの計算が原因なのか特定しましょう。

レンダリング編

カリングをして画面外のオブジェクトは描画しないようにしよう

画面外のオブジェクトはどうせ見えないのであれば描画しないようにするほうが処理が軽くなります。他にもLODを使用することでも軽くなるので使用を検討しましょう。

物理編

固定時間ステップの値を調整しよう

固定時間ステップとはFixedUpdateなどの実行間隔の時間です。例えば0.02であれば0.02秒間隔で実行されます。値を小さくすれば正確な物理表現ができますが処理負荷がかかります。なので処理を軽くしたいときは物理表現が雑にならない程度に値を大きくすることを検討しましょう。

UI編

CanvasにUIをまとめるときはよく考えよう

UIは頂点の移動や表示、非表示などなにか変化があった場合にリビルドされます。このリビルドという動作は重く、Canvas単位で行われます。なのでCanvasの子要素に一つでも頻繁に変化するオブジェクトがあった場合、他のオブジェクトが一切変更がなかったとしてもまとめて再構築されるのでDOTWeenなどでアニメーションするUIはそれ単体でまとめてしまったほうが処理負荷は下がると思います。

UIについているGraphicRayCasterは必要なければオフにしよう

処理負荷も下がりますし、ボタンなどのUIは複数枚重なると押しているのに反応しないなどよくわからないバグが発生してその原因になる可能性もあるのでRay系は必要なければ取り除きましょう。

C#、コーディング編

なるべくInstantiate,Destroy関数を使うのは控えよう

どちらも重い処理なのでUpdateで頻繁に生成、破棄を繰り返すのはやめましょう。生成する数がある程度決まっているならObjectPoolを使うことを検討しましょう。ObjectPoolはUnityの機能やUniRxに入っているので試しに使ってみましょう。

GetComponent、GameObject.Findを使うのは控えよう

これらの機能をUpdateなどで頻繁に使うのは控えましょう。GetComponentに関しては内部でオブジェクトにアタッチしているコンポーネントを検索しています。Findもシーンのオブジェクトを検索しているのでコンポーネントやオブジェクトの数が増えれば増えるほど処理負荷が増します。この場合はAwake、Start時に変数に検索結果を格納してキャッシュしておくことで負荷を軽減できます。他にも[SeliarizeField]を使ってインスペクター上で設定しておいてもいいと思います。

.transformや.rigidbodyも使うのは控えよう

こちらも内部的にはGetComponentを呼んでいるので変数に格納してキャッシュしておくことで負荷を軽減できます。なのでよく使う機能や変数に関してはキャッシュしてみることをおすすめします。他にもQuaternion や Vector3、使い方によってはposition、rotation単位でキャッシュしたほうが処理効率が良くなると思います。

文字列の比較は控えよう

文字列は便利ですが処理負荷がかかりやすいです。しかもスクリプトに直接書くとタイピングミスや仕様変更に弱くなるので気をつけて使いましょう。比較するときは文字列ではなくタグを使用してCompareTagで比較したり、ハッシュ値を利用しましょう。

空のイベント関数(Start、Update)は消しておこう

スクリプトを作成して開くとデフォルトでStartとUpdateがありますが、使ってないStart、Updateを残していても何も処理しないイベント関数を実行するだけなので消しておくと処理負荷は下がるので使わなければ忘れずに消しておきましょう。

距離の比較ではsqrMagnitudeを使おう

具体的には計算時にルートや除算が入ってると計算量が増えるので例えばDistanceも距離を計算する関数ですがこちらのほうが処理が重いです。なのでどんな計算をしているか理解して計算量が多いものは別の方法で解決できないか考えましょう。

まとめ

どうでしたか?このように調べると様々な改善策が出てくると思います。今後もなにか改善策を学んだらここに記載していこうと思います。

目次