(:3[kanのメモ帳]スマートフォン用の表示で見る(:3[kanのメモ帳]個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。実際に手を動かしたりしながら、記事にもしちゃおうという感じの記事です。端的に言えば、より良いゲーム体験のためプロジェクトを見直して適切な形に組み直す事です。実作業としてはプロジェクトの設定、シーンの構成、スクリプトの内容等の見直し、修正をする事でゲームのクオリティを維持したまま、パフォーマンスの向上、メモリの削減を行う事です。最適化はターゲットにしている端末で想定している処理速度が出ない時に行うもので、ターゲットにしている端末で十分快適に遊べているなら無理して行う必要はありません。次に最適化の手順ですが、ざっくり以下のような感じです。今回のメインは1~3の話になります。負荷をどう減らすかの算段をたてる実際に負荷を減らす最適化で特に重要なのが、負荷となっている箇所を特定する事で、これはパレートの法則に当てはめて考えると分かりやすいです。全体の数値の大部分は、全体を構成するうちの一部の要素が生み出しているという理論。80:20の法則、ばらつきの法則とも呼ばれる。Wikipediaようはプロジェクトのごく一部を直せば、大体の問題は解決するので、その一部分を見極めるのが肝心という事です。この負荷となっている箇所を特定するのに必要なのがプロファイリングです。プロファイリングとは処理ごとに掛かった時間、メモリの使用状況を確認する作業の事で、プロファイラと呼ばれるツールを使って行います。Unityにも標準でプロファイラ(Profiler)が付いています。詳細は知りたい場合は各ネイティヴのプロファイラを使いましょう。Profilerから開く事ができます。上部で選択している項目の詳細な情報が下部に表示されるようになっています。実行中だと常に流れ続けてしまうので、確認したい場合はRecordを押して止めるといいでしょう。Profileを有効にしましょう。処理が重くなる点には注意が必要です。Profilerはエディタ上だけでなく、実機上でも使えます。Profiler)から変更出来ます。Buildでビルドしたものでなければ、プロファイリングは行えません。最適化すると言っても状況によって対応手順は様々です。メモリの使用量が多い場合の最適化についてです。メモリの使用量が多い場合は以下のような手順で最適化を行なっていきます。「メモリが足りなくて落ちるとき」とありますが、メモリの使用量が多いだけで落ちる事はなくても手順は同じです。再利用出来なくなっている状態であるメモリリークが発生していないかを確認します。メモリリークが発生しているとメモリ使用量がどんどん増えていくので、メモリの使用量を観測すれば特定し易いです。メモリ使用量の確認はProfilerの下部の詳細(Memoryの部分を押した状態)から行えます。ここの数値が増加し続けて入ればメモリリークが発生している可能性が高いです。長時間遊び続けてると落ちる場合もメモリリークの可能性大です。Sample:Editorを押すとさらに詳細な情報を見る事ができます。2017.1.0f3では上手く動きませんでした。メモリ使用量が多いのはC#?Unity?メモリリークがないのに、メモリ使用量が多い場合は単純に使用してる量が多いという事になります。この時に重要なのが、C#もしくはUnityのどちらで使っているメモリが多いのかという事になります。これは判別するには、メモリリークの時同様、Profilerの下部の詳細(Memoryの部分を押した状態)を確認します。UnityがUnityが使っているメモリで、MonoがC#が使っているメモリになります。Unityのメモリ使用量が多い場合Unityのメモリが多い場合は、TextureやMesh、Animationなどのアセットのデータを大量に読み込んでいる事が原因です。圧縮する(特にアセットストアから持ってきたものリッチ過ぎる事がある)などがあります。C#のメモリ使用量が多い場合C#のメモリが多い場合は、メモリを消費しないようにスクリプトを修正します。ファイルの読み込みや通信時にメモリを消費している場合が多いです。Totalの方も重要になってきます。C#の場合、一度使ったメモリはC#側で予約され、解放したとしてもゲームを終了するまでUnity側で使う事が出来なくなります。(C#側での再利用は出来る)なので、ファイルの読み込みや通信等で一度に大量に使ってる場合は注意が必要です。実機で確認する事をオススメします。ロードが長い場合ロードが長い場合は以下のような手順で最適化を行なっていきます。YouTubeプロファイリング中はDebug.LogをOFFに便利なDebug.Logですが、その処理はかなり重かったりします。プロファイリング中は無効にしましょう。場合によってはこれだけロード時間の短縮に繋がります。false;もしくはDebugクラスを書き換えるという方法もあります。初期化が長い?ロードが長い?ロードが長いと感じていても、実際はロード後の初期化処理が長い場合があります。どちらが長いが調べる必要があります。Usageの部分を押した状態)を確認します。msをクリックすると処理に掛かった時間順にソートが出来ます。上記の例ではNewBehavioursScriptのAwakeで71msも掛かっており、ロードではなく初期化が長いのだと分かります。この場合はスクリプトを修正していく事になります。Thread以外の処理も確認する事ができます。読み込んでいるデータを確認します。必要ないものがあれば読み込まないようにし、データサイズが大き過ぎれば圧縮するようにすれば、ロード時間を短縮できます。AssetBundleを使ってる場合、重複したデータを含んでいる場合があるので注意が必要です。一瞬だけ画面が固まる場合は以下のような手順で最適化を行なっていきます。Collection(GC)が発生していないかどうか一瞬だけ画面が固まる場合はGCが発生している事が多いので、まずこれを確認します。未使用のメモリを再利用出来るようにする処理です。メモリリークが起きなくなるため、便利な機能ですが、膨大な処理時間が掛かります。Collector以外をグラフに出さないようにすると確認しやすいです。(左の四角をクリックすると切り替えが出来る)GCが発生していると以下のようにグラフがいきなり跳ね上がるので、容易に発見できると思います。下部の詳細では実際にGCが起きている所のメソッドでGC.Collectと表示されます。Allocの項目で消費しているメモリを確認する事が出来ます。(クリックでソートする事も出来ます。文字列結合等をする度にメモリを使用してしまうので、StringBuilderを使うようにしましょう。他にもRaycast系や、enumがKeyのDictionaryの参照等も(UnityやC#のバージョンによるかも)メモリを消費してしまうので、Update等の頻繁に実行される所では使わないようにしましょう。GCが発生していない場合GCが発生していない場合、ロード等の単純に重い処理を実行してると思われるのでそれを探し、修正していきます。その辺の話は後編の常にフレームレート低い場合をご参照ください。おわりに記事が長くなり過ぎそうなので、今回はここまで。はてなブログPro個人ゲーム開発者。ω、)_新作は札束風呂VRや神巫女。Policy広告はてなブログをはじめよう!kan_kikuchiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。