# 프로파일러 카운터 시각화

> Add profiler counters to custom Profiler modules.

[프로파일러 카운터를 코드에 추가](/engine/6000.0/manual/analysis/profiler/adding-information-code/add-counters-code.md)하고 나면 프로파일러 창 또는 애플리케이션 빌드에서 프로파일러 카운터를 시각화할 수 있습니다.

## 프로파일러 창에서 커스텀 카운터 시각화

프로파일러 창에서 `ProfilerCounter` 또는 `ProfilerCounterValue`가 생성하는 데이터를 보려면 [커스텀 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);
    }
}
```

총알 카운트를 프로파일러에 전달하기 위해, 이 예시에서는 총알 라이프사이클을 관리하는 셸 스크립트가 있다고 가정합니다. 그런 다음 `GameStats.BulletCount` 값을 `Awake` 단위로 증가시키고 `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)하여 빌트인 카운터 또는 새로 추가된 카운터를 선택해 시각화합니다. Profiler 모듈 에디터를 여는 과정은 다음과 같습니다.

1. 프로파일러 창(**Window > Analysis > Profiler**)을 엽니다.
2. 창 왼쪽 상단의 Profiler 모듈 드롭다운을 선택합니다. 톱니바퀴 아이콘을 클릭하면 Profiler 모듈 에디터가 새 창에서 열립니다.
3. **Add**를 선택한 다음 창 오른쪽의 **User** 리스트에서 시각화할 카운터를 선택합니다.

**중요:** 프로파일러 창에 로드한 데이터가 없다면 생성한 카운터가 Profiler 모듈 에디터를 로드할 때 Available Counters 창에 표시되지 않습니다. 커스텀 카운터를 보려면 프로파일러로 카운터가 있는 [일부 데이터를 캡처하거나 로드](/engine/6000.0/manual/analysis/profiler/collect-data.md)한 뒤 Profiler 모듈 에디터를 다시 엽니다.

그러면 프로파일러 창에서 다른 카운터들과 함께 데이터를 볼 수 있습니다. 자세한 내용은 [커스텀 Profiler 모듈 생성](/engine/6000.0/manual/analysis/profiler/collect-data/visualizing-data/customizing/creating-custom-modules.md)을 참고하십시오.


**프로파일러 창에 커스텀 카운터가 있는 모듈.:**
![](/api/media?file=/engine/6000.0/media/images/profiler-window-custom-module.png)

**참고:** 정적으로 선언된 카운터는 유형이 초기화될 때 C# 코드에서 동적으로 초기화되며 실제로 초기화되고 사용되기 전까지 사용할 수 없습니다. 이는 편집 모드와 플레이 모드에 적용됩니다. 카운터가 Profiler 모듈 에디터에 표시되지 않으면 먼저 몇 프레임 동안 프로파일러로 [일부 데이터를 기록](/engine/6000.0/manual/analysis/profiler/collect-data/profiling-applications/profiling-target-device.md)하십시오.

## 빌드된 플레이어에서 프로파일러 카운터 시각화

빌드된 플레이어에서 프로젝트를 실행하면 프로파일러 창에 액세스할 수 없습니다. 하지만 빌드된 플레이어에서 카운터를 UI 요소로서 표시할 수 있습니다. 이는 애플리케이션 빌드에 프로파일링 툴을 포함할 수 있다는 의미입니다.

다음은 빌드된 플레이어에서 커스텀 UI를 사용하여 씬의 왼쪽 상단에 카운터를 표시한 이미지입니다.


**커스텀 정보 오버레이가 있는 탱크 게임:**
![](/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)
* [Profiler 모듈 에디터 레퍼런스](/engine/6000.0/manual/analysis/profiler/collect-data/visualizing-data/customizing/module-editor.md)
