# プロファイラーカウンターの可視化

> Add profiler counters to custom Profiler modules.

[プロファイラーカウンターにコードを追加](/engine/6000.0/manual/analysis/profiler/adding-information-code/add-counters-code.md)すると、Profiler ウィンドウ、またはアプリケーションのビルドで可視化することができます。

## Profiler ウィンドウでのカスタムカウンターの可視化

`ProfilerCounter` または `ProfilerCounterValue` で生成されるデータを Profiler ウィンドウで表示するには、[カスタム Profiler モジュール](/engine/6000.0/manual/analysis/profiler/collect-data/visualizing-data/customizing.md)を使用することができます。これにより、他のシステムメトリクスとの関係を視覚的に認識し、パフォーマンスの問題を迅速に特定できるようになります。

### コードへのメトリクスの追加

以下の例は、GameManager クラスが高レベルのロジックを処理し、敵について知っていることを前提としています。カウンターの値を更新するには、`Update` メソッドまたは `LateUpdate` メソッドで (ロジックが敵のスポーンまたは破壊とともに実行されるタイミングに応じて)、`Sample` メソッドを使用して敵のカウント値をプロファイラーにプッシュします。

```lang-csharp
using UnityEngine;
using Unity.Profiling;

class GameManager : MonoBehaviour
{
    Enemy[] m_Enemies;

    void Update()
    {
        GameStats.EnemyCount.Sample(m_Enemies.Length);
    }
}
```

この例では、弾丸の数をプロファイラーに渡すために、弾丸のライフライフサイクルを管理するシェルスクリプトがあることを前提としています。その後、`Awake` で `GameStats.BulletCount` の値を増やし、`OnDestroy` で値を減らすことで、ゲーム内の現在の弾丸の流れに関する正確な情報を提供します。

```lang-csharp
using UnityEngine;
using Unity.Profiling;

public class Shell : MonoBehaviour
{
    void Awake()
    {
        GameStats.BulletCount.Value += 1;
    }
    void OnDestroy()
    {
        GameStats.BulletCount.Value -= 1;
    }
}
```

\*\*注：\*\*Unity は、開発ビルド以外では `ProfilerCounter` と `ProfilerCounterValue` の両方をコンパイルします。

### Profiler ウィンドウにカスタムモジュールを追加する

[プロファイラーモジュールエディター](/engine/6000.0/manual/analysis/profiler/collect-data/visualizing-data/customizing/module-editor.md)を使用して、ビルトインまたは新しく追加したカウンターを可視化の対象として選択します。プロファイラーモジュールエディターを開くには、以下のようにします。

1. Profiler ウィンドウを開きます (**Window > Analysis > Profiler** を選択します)。
2. ウィンドウの左上にある Profiler Module ドロップダウンを選択します。歯車アイコンを選択すると、新しいウィンドウが開いてプロファイラーモジュールエディターが表示されます。
3. **Add** を選択し、可視化したいカウンターを、ウィンドウの右側の **User** リストから選択します。

\*\*重要：\*\*Profiler ウィンドウにデータをロードしていないと、作成したカウンターは、プロファイラーモジュールエディターをロードしたときに Available Counters ペインに表示されません。カスタムカウンターを表示するには、作成したカウンターを含むデータをプロファイラーで[キャプチャまたはロード](/engine/6000.0/manual/analysis/profiler/collect-data.md)して、プロファイラーモジュールエディターを再度開きます。

その後、Profiler ウィンドウで他のカウンターと一緒にデータを表示することができます。詳細については、[カスタムプロファイラーモジュールの作成](/engine/6000.0/manual/analysis/profiler/collect-data/visualizing-data/customizing/creating-custom-modules.md)を参照してください。


**Profiler ウィンドウでカスタムカウンターを持つモジュール。:**
![](/api/media?file=/engine/6000.0/media/images/profiler-window-custom-module.png)

\*\*注：\*\*静的として宣言されたカウンターは、型を初期化する際に C# コードで動的に初期化されます。実際に初期化され、使用するまで利用できない場合があります。これは編集モードと再生モードの両方に適用されます。プロファイラーモジュールエディターにカウンターが表示されない場合は、まず[プロファイラーで数フレーム分のデータを記録](/engine/6000.0/manual/analysis/profiler/collect-data/profiling-applications/profiling-target-device.md)してください。

## ビルドされたプレイヤーでプロファイラーカウンターを可視化する

ビルドされたプレイヤーでプロジェクトを実行した場合、Profiler ウィンドウにはアクセスできません。ただし、ビルドされたプレイヤーで UI 要素としてカウンターを表示することができます。つまり、アプリケーションのビルドにプロファイリングツールを入れることができます。

以下の画像は、ビルドされたプレイヤーでカスタム UI を使用して、シーンの左上にカウンターを表示しています。


**カスタム情報がオーバーレイされた Tanks ゲーム:**
![](/api/media?file=/engine/6000.0/media/images/Tanks-Runtime-Stats.png)

**注：**(開発ビルドではない) リリース版のプレイヤーでは、すべてのプロファイラーカウンターを利用できるわけではありません。[`ProfilerRecorder.Valid`](/engine/6000.0/script-reference/unity-profiling/profiler-recorder/valid.md) を使用して、データが利用可能で、プロファイラーがデータを記録できるかどうかを判断します。または、[`ProfilerRecorderHandle.GetAvailable`](/engine/6000.0/script-reference/unity-profiling-low-level-unsafe/profiler-recorder-handle/get-available.md) を使用して、使用可能なすべてのプロファイラー統計を列挙することができます。

### プレイヤーでカウンター値を取得する

プロファイラーのカウンターは、ゲームやエンジンシステムの重要なメトリクスに関するインサイトを提供します。継続的なインテグレーション設定がある場合、またはテスト再生中にアプリケーションの主要なパフォーマンス指標を視覚化したい場合は、[`ProfilerRecorder`](/engine/6000.0/script-reference/unity-profiling/profiler-recorder.md) API を使用してカスタムおよびビルトインプロファイラーのカウンター値を取得できます。

例えば、以下のスクリプトは、フレーム時間、Mono/IL2CPP ヒープサイズ、およびアプリケーションが使用するメモリの合計量を表示します。

```lang-csharp
using System.Collections.Generic;
using System.Text;
using Unity.Profiling;
using UnityEngine;

public class StatsScript : MonoBehaviour
{
    string statsText;
    ProfilerRecorder systemMemoryRecorder;
    ProfilerRecorder gcMemoryRecorder;
    ProfilerRecorder mainThreadTimeRecorder;

    double GetRecorderFrameAverage(ProfilerRecorder recorder)
    {
        var samplesCount = recorder.Capacity;
        if (samplesCount == 0)
            return 0;

        double r = 0;
        unsafe
        {
            var samples = stackalloc ProfilerRecorderSample[samplesCount];
            recorder.CopyTo(samples, samplesCount);
            for (var i = 0; i < samplesCount; ++i)
                r += samples[i].Value;
            r /= samplesCount;
        }

        return r;
    }

    void OnEnable()
    {
        systemMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "System Used Memory");
        gcMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Reserved Memory");
        mainThreadTimeRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Internal, "Main Thread", 15);
    }

    void OnDisable()
    {
        systemMemoryRecorder.Dispose();
        gcMemoryRecorder.Dispose();
        mainThreadTimeRecorder.Dispose();
    }

    void Update()
    {
        var sb = new StringBuilder(500);
        sb.AppendLine($"Frame Time: {GetRecorderFrameAverage(mainThreadTimeRecorder) * (1e-6f):F1} ms");
        sb.AppendLine($"GC Memory: {gcMemoryRecorder.LastValue / (1024 * 1024)} MB");
        sb.AppendLine($"System Memory: {systemMemoryRecorder.LastValue / (1024 * 1024)} MB");
        statsText = sb.ToString();
    }

    void OnGUI()
    {
        GUI.TextArea(new Rect(10, 30, 250, 50), statsText);
    }
}
```

**重要：**`ProfilerRecorder.Dispose` を使用して、`ProfilerRecorder` に関連付けられたアンマネージリソースを解放します。

## エディターのプロファイラーフレームデータからカウンター値を取得する

エディターでプロファイラーフレームデータを処理するときにプロファイラーカウンターの値を取得するには、[`FrameDataView`](/engine/6000.0/script-reference/unity-editor-profiling/frame-data-view.md) API を使用します。

[`FrameDataView.GetCounterValueAsInt`](/engine/6000.0/script-reference/unity-editor-profiling/frame-data-view/get-counter-value-as-int.md)、[`FrameDataView.GetCounterValueAsLong`](/engine/6000.0/script-reference/unity-editor-profiling/frame-data-view/get-counter-value-as-long.md)、[`FrameDataView.GetCounterValueAsFloat`](/engine/6000.0/script-reference/unity-editor-profiling/frame-data-view/get-counter-value-as-float.md)、および [`FrameDataView.GetCounterValueAsDouble`](/engine/6000.0/script-reference/unity-editor-profiling/frame-data-view/get-counter-value-as-double.md) を使用して、以下のように特定のカウンターのフレーム値を取得できます。

```lang-csharp
using UnityEditor.Profiling;

class Example
{
    static int ExtractMyCounterValue(FrameDataView frameData, string counterName)
    {
        var counterMarkerId = frameData.GetMarkerId(counterName);
        return frameData.GetCounterValueAsInt(counterMarkerId);
    }
}
```

## 追加リソース

* [コードへのプロファイラーカウンターの追加](/engine/6000.0/manual/analysis/profiler/adding-information-code/add-counters-code.md)
* [プロファイラーモジュールエディターのリファレンス](/engine/6000.0/manual/analysis/profiler/collect-data/visualizing-data/customizing/module-editor.md)
