Unity入門

【Unity】パフォーマンス最適化・デバッグ完全ガイド|プロファイラー・GC対策・軽量化テクニックまとめ

この記事でわかること

  • Unityのデバッグツール(コンソール・プロファイラー・フレームデバッガー)の使い方
  • CPU・GPU・メモリ負荷の最適化テクニック
  • オブジェクトの動的管理(プーリング・GC対策)
  • パフォーマンス改善のベストプラクティス

UnityのDebugとは?

ピッグダディ

今日は「Unityのパフォーマンス最適化とデバッグ」について解説していこう。
重くなったり、カクついたりするゲームをどう改善するかがテーマだよ。

ピッグボーイ

あ、プロファイラーって聞いたことあります!
でも見方が分からなくて、どこを直せばいいのかピンと来なかったです。

ピッグガール

私はメモリの使いすぎでアプリがクラッシュしたことがあって。
GCとかオブジェクトプールって対策になるって聞いたけど、使い方が難しくて…

ピッグダディ

うんうん、そういう悩みは多いよね。
このページでは、プロファイラーやフレームデバッガの使い方から、CPU・メモリ負荷の軽減、GC対策、軽量化までわかりやすくまとめていくよ!

Unityのデバッグツール

Unityには、開発中のバグを見つけたり、パフォーマンスの問題を解析するためのツールが用意されています。

コンソール(デバッグログ)

Debug.Log()を使えば、コードの状態を確認できます。
エラーの発生箇所を特定するのに便利!

Debug.Log("ゲーム開始!");
Debug.LogWarning("警告:データが保存されていません");
Debug.LogError("エラー:スクリプトが動作していません");

※ Consoleについてわからない方はこちらを参考にしてください。

プロファイラー(パフォーマンス解析)

Window→ Analysis→Profilerを開くと、CPU・GPU・メモリの負荷を確認できます。
ゲームが重い場合、プロファイラーでCPU/GPUのボトルネックを特定!

プロファイラーの項目説明用途
CPU Usageスクリプト、レンダリング、物理演算、ガベージコレクションなど、異なるプロセスに費やされるCPU時間を測定。スクリプトやレンダリングのボトルネックを特定し、CPUパフォーマンスを最適化。
Renderingドローコール、カリング、バッチ処理、GPU処理など、レンダリングのパフォーマンスを追跡。ドローコールを削減し、シェーダーを最適化してフレームレートを向上。
Memoryテクスチャ、オブジェクトの割り当てなど、メモリの割り当てと使用状況を監視。メモリリークの管理、GC割り当ての削減、アセットのロードを最適化。
Audioミキシング、DSP、遅延などのオーディオ処理を分析。スムーズなオーディオ再生を保証し、遅延やパフォーマンスの問題を診断。
Videoビデオの再生とデコードのパフォーマンスをプロファイル。ビデオ再生を最適化し、スムーズなパフォーマンスを実現。
Physics物理演算の計算とCPUへの影響を調査。不要なリジッドボディの相互作用を減らして物理演算を最適化。
Physics(2D)2D物理演算の計算を特に監視し、最適化。2Dゲームの物理演算を最適化し、効率的な処理を実現。
UIレイアウト計算やレンダリング時間など、UIのパフォーマンスを追跡。UIのパフォーマンスを最適化し、レスポンスの向上やフレーム落ちを防止。
UI DetailsUI要素の詳細なパフォーマンス影響を分析。複雑なレイアウトに関連するUIパフォーマンスの問題を特定し、修正。
Realtime GIリアルタイムのグローバルイルミネーション計算を監視。リアルタイムのライティング計算を最適化し、パフォーマンス向上。
Virtual TexturingUnityの仮想テクスチャリングシステムのパフォーマンスとメモリ使用状況を分析。テクスチャのストリーミングを改善し、高品質なアセットを低メモリで実現。

フレームデバッガ(描画負荷の確認)

Window→ Analysis→Frame Debuggerを開くと、どのオブジェクトが負荷をかけるかを確認できます。

オーバードロー(透明なオブジェクトの重なり)をチェック!
ドローコール(描画回数)が多い場合、バッチ処理を最適化!

CPU・GPUの負荷を軽減する方法

Update()の最適化

Update()は毎フレーム実行されるため、処理が重いとフレームレートが低下します。
不要な処理を減らし、負荷を分散!

//Update() の負荷を軽減
void Update()
{
    if (Time.frameCount % 10 == 0) // 10フレームに1回実行
    {
        CheckObjects();
    }
}

物理演算の最適化

FixedUpdate()で処理する物理演算は、必要なオブジェクトのみ適用しましょう。
物理演算の精度を向上し、カクつきを防ぐ!

//RigidbodyInterpolationを有効化
rigidbody.interpolation = RigidbodyInterpolation.Interpolate;

GPU負荷の軽減

・影のクオリティを調整(Quality Settings)
・不要なライティングを削減(Baked Light活用)
・テクスチャサイズを縮小し、メモリ使用量を最適化

メモリ管理とGC(ガベージコレクション)対策

不要なオブジェクトを削除

オブジェクトをDestroy()するだけでは、メモリは解放されません。
UnloadUnusedAssets()で不要なテクスチャやオブジェクトを削除!

//メモリ解放
Destroy(gameObject);
Resources.UnloadUnusedAssets();
System.GC.Collect();

スクリプトでGCを最適化

List<>やstringを定期的に生成すると、GC(ガベージコレクション)が発生し、カクつく原因になります。
StringBuilderを使うと、GC発生を抑えられる!

using System.Text;

//文字列結合StringBuilderを変更
StringBuilder sb = new StringBuilder();
sb.Append("スコア: ");
sb.Append(100);
Debug.Log(sb.ToString());

オブジェクトプール(Pooling)の活用

オブジェクトの生成・削除を繰り返すと、メモリリークの原因になります。
Poolingを使うことで、オブジェクトを使い捨てすることができます。
オブジェクトを使い捨てることで、メモリ管理を最適化!

//オブジェクトプールの実装
using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour
{
    public GameObject prefab;
    private Queue<GameObject> pool = new Queue<GameObject>();

    public GameObject GetObject()
    {
        if (pool.Count > 0)
        {
            GameObject obj = pool.Dequeue();
            obj.SetActive(true);
            return obj;
        }
        return Instantiate(prefab);
    }

    public void ReturnObject(GameObject obj)
    {
        obj.SetActive(false);
        pool.Enqueue(obj);
    }
}

ゲームを軽量化するテクニック

テクスチャサイズを最適化

・Texture Import Settingsで解像度を圧縮(512×512など)

AudioClipの圧縮

・Load TypeをStreamingすると、BGMのメモリ負荷を軽減します!
・SE(効果音)をCompressed In Memory選択!

シーンロードを最適化

シーンのロード時間が長い場合、非同期ロード(LoadSceneAsync())を使って、スムーズな切り替えが可能です。
ロード画面を入れて、ユーザー体験を向上!

SceneManager.LoadSceneAsync("GameScene");

まとめ

・プロファイラーを活用して、CPU・GPU・メモリのボトルネックを特定!
・Update()の最適化で、無駄な処理を削減!
・オブジェクトプールを使って、メモリ使用量を最適化!
・テクスチャ・オーディオを圧縮して、ファイルサイズを削減!