Version: 2023.1
언어: 한국어
유닛 테스트
스크립팅 개념

Roslyn 분석기 및 소스 제너레이터

Unity 프로젝트에서 Roslyn 분석기, 소스 제너레이터, 규칙 집합 파일을 사용하여 코드의 스타일, 품질, 기타 문제를 검사합니다.

기존의 분석기 라이브러리를 사용하여 코드를 검사하고, 직접 분석기를 작성하여 조직 내에 베스트 프랙티스나 규칙을 홍보할 수 있습니다. 이 페이지는 빈 Unity 프로젝트에서 Roslyn 분석기와 소스 제너레이터를 사용하는 방법을 설명합니다.

참고: Roslyn 분석기는 Visual Studio 및 JetBrains Rider와 같은 Unity가 공개적으로 지원하는 IDE와만 호환됩니다.

Roslyn 분석기 작성 및 사용 방법에 대한 자세한 내용은 Microsoft의 분석기 구성Roslyn 분석기 시작 문서를 참조하십시오.

소스 제너레이터

스크립트 컴파일 프로세스의 추가 단계로 소스 제너레이터를 사용할 수 있습니다. 소스 제너레이터를 사용하여 기존 코드를 컴파일하는 동안 새 코드를 추가할 수 있습니다. 분석기와 마찬가지로 기존 소스 제너레이터를 사용하거나 직접 생성할 수 있습니다.

참고: Unity는 ‘System.Text.Json’ 네임스페이스의 6.0.0 프리뷰 버전만 지원합니다. 애플리케이션에서 이 네임스페이스를 사용하려면 6.0.0. 프리뷰 버전을 사용해야 합니다. System.Text.Json에 대한 자세한 내용은 Microsoft의 System.Text.Json 네임스페이스 문서를 참조하십시오.

Visual Studio를 사용하여 소스 제너레이터를 설정하려면 다음 단계를 따르십시오.

  1. Visual Studio에서 .NET Standard 2.0을 타겟으로 하는 .NET Standard 라이브러리 프로젝트를 만듭니다.
  2. Microsoft.CodeAnalysis NuGet 패키지를 설치합니다. Unity에서 사용하려면 소스 제너레이터가 Microsoft.CodeAnalysis 3.8을 사용해야 합니다.
  3. Visual Studio 프로젝트에서 새 C# 파일을 만들고 다음 코드를 추가합니다.
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Text;

namespace ExampleSourceGenerator
{
    [Generator]
    public class ExampleSourceGenerator : ISourceGenerator
    {
        public void Execute(GeneratorExecutionContext context)
        {
            System.Console.WriteLine(System.DateTime.Now.ToString());

            var sourceBuilder = new StringBuilder(
            @"
            using System;
            namespace ExampleSourceGenerated
            {
                public static class ExampleSourceGenerated
                {
                    public static string GetTestText() 
                    {
                        return ""This is from source generator ");

            sourceBuilder.Append(System.DateTime.Now.ToString());

            sourceBuilder.Append(
                @""";
                    }
    }
}
");

            context.AddSource("exampleSourceGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }

        public void Initialize(GeneratorInitializationContext context) { }
    }
}
  1. 릴리스용 소스 제너레이터를 빌드합니다. 빌드하려면 Build로 이동하여 Batch Build 옵션을 선택합니다.
  2. 소스 제너레이터의 프로젝트 폴더에서 bin/Release/netstandard2.0/ExampleSourceGenerator.dll 파일을 찾습니다.
  3. 이 파일을 Unity 프로젝트의 Assets 폴더에 복사합니다.
  4. 에셋 브라우저 내에서 .dll 파일을 클릭하여 플러그인 인스펙터 창을 엽니다.
  5. 플러그인용 Select platforms로 이동하여 Any Platform을 비활성화합니다.
  6. Include Platforms로 이동하여 EditorStandalone을 비활성화합니다.
  7. Asset Labels로 이동하여 Asset Labels 하위 메뉴를 엽니다.
  8. RoslynAnalyzer라는 새 레이블을 만들고 할당합니다. 이렇게 하려면 에셋 레이블 하위 메뉴의 텍스트 입력 창에 “RoslynAnalyzer”를 입력합니다. 이 레이블은 정확히 일치해야 하며 대소문자를 구분합니다. 첫 번째 분석기에 대한 레이블이 생성되면 Asset Labels 하위 메뉴에 해당 레이블이 나타납니다. 메뉴에서 레이블 이름을 클릭하여 다른 분석기에 할당할 수 있습니다.
  9. 소스 제너레이터가 작동하는지 테스트하려면 다음 코드를 사용하여 에디터에서 새 C# 스크립트를 만듭니다.
using UnityEngine;

public class HelloFromSourceGenerator : MonoBehaviour
{
    static string GetStringFromSourceGenerator()
    {
        return ExampleSourceGenerated.ExampleSourceGenerated.GetTestText();
    }

    // Start is called before the first frame update
    void Start()
    {
        var output = "Test";
        output = GetStringFromSourceGenerator();
        Debug.Log(output);
    }
}
  1. 이 스크립트를 씬의 게임 오브젝트에 추가하고 플레이 모드로 들어갑니다. 타임 스탬프를 포함한 콘솔 창에 소스 제너레이터의 메시지가 표시되어야 합니다.

소스 제너레이터에 대한 자세한 내용은 Microsoft의 소스 제너레이터 문서를 참조하십시오.

분석기 범위

어셈블리 정의를 사용하여 프로젝트에서 코드의 특정 부분만 분석하도록 분석기의 범위를 제한할 수 있습니다.

Unity는 프로젝트의 Assets 폴더에 포함되거나 부모 폴더에 어셈블리 정의 파일이 없는 하위 폴더에 포함된 모든 어셈블리에 적용됩니다. 어셈블리 정의가 있는 폴더나 그러한 폴더의 하위 폴더에 있는 분석기는 해당 어셈블리 정의에서 생성된 어셈블리 및 이러한 어셈블리를 참조하는 다른 어셈블리에만 적용됩니다.

예를 들어 패키지는 패키지와 관련된 코드만 분석하는 분석기를 제공할 수 있음을 의미하며 패키지 사용자가 패키지 API를 올바르게 사용하는 데 도움이 될 수 있습니다.

보고서 분석기 진단

분석기와 소스 제너레이터의 총 실행 시간이나 각 분석기 또는 소스 제너레이터의 상대 실행 시간과 같은 정보를 보려면 Preferences > Diagnostic Switches로 이동하여 EnableDomainReloadTimings를 활성합니다. 활성화되면 정보가 콘솔 창에 표시됩니다.

기존 Roslyn 분석기 또는 소스 제너레이터 설치

Unity는 NuGet을 통한 Roslyn 분석기 및 소스 제너레이터의 설치를 직접 지원하지 않습니다. 아래 예시에서는 ErrorProne.NET.CoreAnalyzers 라이브러리를 사용하여 NuGet에서 Roslyn 분석기 및 소스 제너레이터를 설치하는 방법을 보여줍니다.

  1. Download package 버튼을 사용하여 라이브러리를 .zip 파일로 다운로드합니다.
  2. .zip 파일의 압축을 풉니다.
  3. 압축을 푼 폴더에서 분석기가 포함된 .dll 파일을 찾습니다. 이 예에서는 errorprone.net.coreanalyzers<version-number>\analyzers\dotnet\cd로 이동합니다. 필요한 파일의 파일명은 ErrorProne.NET.Core.dll, ErrorProne.Net.CoreAnalyzers.dll, and RuntimeContracts.dll이며 이 폴더에 있어야 합니다.
  4. 이러한 파일을 Unity 프로젝트의 에셋 폴더 또는 에셋 폴더 안에 중첩된 폴더로 이동합니다. 이렇게 하려면 Assets > Import new asset으로 이동하여 세 파일 각각에 대해 .dll을 선택하거나 기기의 파일 브라우저를 통해 프로젝트의 에셋 폴더에 복사합니다.
  5. Unity 내부의 Asset Browser에서 .dll 파일을 클릭하여 플러그인 인스펙터 창을 엽니다.
  6. 플러그인 인스펙터 창에서 다음을 수행합니다.
    • Select platforms for plugin 제목 아래에서 Any Platform을 비활성화합니다.
    • Include Platforms 제목 아래에서 EditorStandalone을 비활성화합니다.
  7. 플러그인 인스펙터 창의 Asset Labels 제목 아래에서 파란색 레이블 아이콘을 클릭하여 Asset Labels 하위 메뉴를 엽니다.
  8. RoslynAnalyzer라는 새 레이블을 만들고 할당합니다. 이렇게 하려면 Asset Labels 하위 메뉴의 텍스트 입력 창에 “RoslynAnalyzer”를 입력하고 Return을 누릅니다. 이 레이블은 예와 정확히 일치해야 하며 대소문자를 구분합니다. 첫 번째 분석기에 대한 레이블이 생성되면 Asset Labels 하위 메뉴의 사용 가능한 레이블 리스트에 나타납니다. 메뉴에서 레이블 이름을 클릭하여 다른 분석기에 할당할 수 있습니다.

Unity는 RoslynAnalyzer 레이블을 인식하고 이 레이블이 있는 에셋을 Roslyn 분석기 또는 소스 제너레이터로 취급합니다. 레이블을 분석기에 할당하면 Unity는 분석기의 범위 내에서 스크립트를 다시 컴파일하고 분석기의 규칙에 따라 해당 스크립트의 코드를 분석합니다. 분석기와 동일한 어셈블리 정의 내에 있는 모든 스크립트는 해당 분석기의 범위에 있습니다. 에셋 폴더의 루트 수준에 있는 분석기의 경우 Unity는 프로젝트의 모든 파일이 범위 내에 있는 것으로 간주합니다. 범위에 대한 자세한 내용은 위의 분석기 범위를 참조하십시오.

분석기가 올바르게 작동하는지 테스트하려면 아래 예시를 따릅니다. 분석기를 올바르게 설치한 경우 ErrorProne.NET 분석기는 예시 코드를 분석할 때 경고를 발생시킵니다.

RethrowError.cs라는 새 스크립트 파일을 만듭니다. 다음 코드를 이 스크립트에 복사하고 파일을 저장합니다.

using System;
using UnityEngine;

public class RethrowError : MonoBehaviour
{
    void Update()
    {
        try
        {
            DoSomethingInteresting();
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
            throw e;
        }
    }

    private void DoSomethingInteresting()
    {
        throw new System.NotImplementedException();
    }
}

파일을 저장하면 Unity가 스크립트를 다시 컴파일하고 스크립트 코드에서 적용 가능한 분석기를 실행합니다. ErrorProne.NET 분석기가 올바르게 설치되면 콘솔 창에 위 코드에 대한 다음과 같은 경고가 표시됩니다.

Assets\RethrowError.cs(14,23): warning EPC12: Suspicious exception handling: only e.Message is observed in exception block.

Assets\RethrowError.cs(15,19): warning ERP021: Incorrect exception propagation. Use throw; instead.

규칙 집합 파일

프로젝트의 분석기가 표시하는 다양한 경고와 오류를 처리하는 방법에 대한 고유한 규칙을 정의하기 위해 규칙 집합 파일을 작성할 수 있습니다. 커스텀 규칙 집합을 만드는 방법에 대한 자세한 내용은 커스텀 규칙 집합을 만드는 방법에 대한 Microsoft의 Visual Studio 문서를 참조하십시오.

에셋 루트 폴더에 Default.ruleset이라는 이름의 규칙 집합 파일을 배치합니다. Default.ruleset에서 정의한 규칙은 Assembly-CSharp.dll과 같은 모든 사전 정의된 어셈블리 및 .asmdef 파일을 사용하여 빌드된 모든 어셈블리에 적용됩니다.

사전 정의된 어셈블리에 대해 Default.ruleset의 규칙을 오버라이드하려면 루트 폴더에 [PredefinedAssemblyName].ruleset이라는 이름의 .ruleset 파일을 만듭니다. 예를 들어, Assembly-CSharp.ruleset의 규칙은 Assembly-CSharp.dll의 코드에 적용됩니다. 루트 폴더에서는 다음의 .ruleset 파일만 허용됩니다.

  • Default.ruleset
  • Assembly-CSharp.ruleset
  • Assembly-CSharp-firstpass.ruleset
  • Assembly-CSharp-Editor.ruleset
  • Assembly-CSharp-Editor-firstpass.ruleset

워크플로: Unity에서 규칙 집합 파일 테스트

Unity에서 규칙 집합 파일을 테스트하려면 다음 단계를 따르십시오.

단계 1: 규칙 집합 파일 설정

  1. 프로젝트의 에셋 폴더 안에 “Subfolder”라는 하위 폴더를 만듭니다.
  2. Subfolder 안에서 다음을 수행합니다.
    1. 새 .asmdef 파일을 만듭니다.
    2. RethrowError.cs의 복사본을 저장합니다.
  3. 다음 코드를 사용하여 Assets* 안에 Default.ruleset 파일을 만듭니다.
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
  <Rules AnalyzerId="ErrorProne.NET.CodeAnalyzers" RuleNamespace="ErrorProne.NET.CodeAnalyzers">
    <Rule Id="ERP021" Action="Error" />
  <Rule Id="EPC12" Action="None" />
  </Rules>
</RuleSet>

Default.ruleset 파일은 다음 규칙을 정의합니다.

  • 의심스러운 예외 처리에 대한 경고인 EPC12를 억제합니다.
  • 잘못된 예외 전파에 대한 경고인 ERP021을 오류로 높입니다.

단계 2: 프로젝트 다시 로드

프로젝트에 규칙 집합 파일을 추가한 후 규칙을 적용해야 하는 어셈블리에 있는 모든 스크립트를 다시 임포트합니다. 이렇게 하면 Unity가 새 규칙 집합 파일을 사용하여 어셈블리를 다시 컴파일합니다. 재컴파일 후 콘솔 창에 두 개의 메시지가 표시되어야 합니다.

Assets\Subfolder\RethrowError.cs(15,19): error ERP021: Incorrect exception propagation. Use throw; instead.

Assets\RethrowError.cs(15,19): error ERP021: Incorrect exception propagation. Use throw; instead.

Unity는 Default.ruleset에 정의된 규칙을 Assets/RethrowError.csAssets/Subfolder/RethrowError.cs에 모두 적용합니다.

단계 3: 커스텀 규칙 집합 추가

Assets/Subfolder에서 .ruleset 파일을 만들고 원한는 이름(여기에서는 exampleHello.ruleset)을 지정합니다.

<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
  <Rules AnalyzerId="ErrorProne.NET.CodeAnalyzers" RuleNamespace="ErrorProne.NET.CodeAnalyzers">
    <Rule Id="ERP021" Action="Info" />
    <Rule Id="EPC12" Action="Info" />
  </Rules>
</RuleSet>

이 새로운 Hello.ruleset 파일은 경고나 오류로 처리하지 않고 EPC12와 ERP021을 콘솔에 출력하도록 Unity에 지시합니다.

Unity가 프로젝트를 다시 컴파일하면 콘솔 창에 다음의 메시지가 표시됩니다.

Assets\Subfolder\RethrowError.cs(14,23): info EPC12: Suspicious exception handling: only e.Message is observed in exception block.

Assets\Subfolder\RethrowError.cs(15,19): info ERP021: Incorrect exception propagation. Use throw; instead.

Assets\RethrowError.cs(15,19): error ERP021: Incorrect exception propagation. Use throw; instead.

Default.ruleset의 규칙이 Assets\RethrowError.cs에 여전히 적용되지만, Assets\Subfolder\RethrowError.cs에는 더 이상 적용되지 않는데, 이는 Hello.ruleset의 규칙에 의해 오버라이드되기 때문입니다.

허용되는 모든 규칙 집합 작업 파일에 대한 자세한 내용은 코드 분석 규칙 집합 에디터 사용에 대한 Visual Studio 문서를 참조하십시오.

추가 분석기

다음은 인기 있는 다른 Roslyn 분석기 라이브러리의 Github 저장소에 대한 링크입니다.

유닛 테스트
스크립팅 개념