コードのスタイルや品質、その他の問題を検査するには、Unity プロジェクトで Roslyn アナライザー、ソースジェネレーター、ルールセットファイルを使用します。
既存のアナライザーライブラリを使用してコードを検査したり、独自のアナライザーを作成して組織内の効率的な方法や規則を推進したりすることができます。このページでは、空の Unity プロジェクトで Roslyn アナライザーとソースジェネレーターを使用する方法を説明します。
ノート: Roslyn アナライザーは、Unity が公式にサポートしている IDE、すなわち Visual Studio と JetBrains Rider にのみ対応しています。
Roslyn アナライザーの書き方と使用方法の詳細については、Microsoft の概要 およびRoslyn アナライザーの概要 のドキュメントを参照してください。
ソース ジェネレーターは、スクリプトのコンパイルプロセスの追加手順として使用できます。ソースジェネレーターを使用すると、既存のコードをコンパイルしている間に新しいコードを追加することができます。アナライザーのように、既存のソースジェネレーターを使用することも、独自のソースジェネレーターを作成することもできます。
ノート: Unity は ‘System.Text.Json’ 名前空間のバージョン 6.0.0-preview のみをサポートしています。アプリケーションでこの名前空間を使用する場合は、バージョン 6.0.0-preview を使用するようにしてください。 System.Text.Json
の詳細については、Microsoft のSystem.Text.Json 名前空間 ドキュメントを参照してください。
Visual Studio を使用してソースジェネレーターをセットアップするには、以下を行います。
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) { }
}
}
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);
}
}
ソースジェネレーターに関する詳細については、Microsoft の ソース ジェネレーター ドキュメントを参照してください。
アセンブリ定義を使用することで、プロジェクトのアナライザーのスコープを制限することができます。これにより、コードの特定の部分のみを分析します。
Unity は、プロジェクトの Assets フォルダー内、または親フォルダーに アセンブリ定義ファイル が含まれていないサブフォルダー内のすべてのアセンブリにアナライザーを適用します。アナライザーがアセンブリ定義を含むフォルダー、またはそのようなフォルダーのサブフォルダーにある場合、アナライザーはそのアセンブリ定義から生成されたアセンブリと、それを参照するアセンブリ定義にのみ適用されます。
つまり、例えば パッケージ は、そのパッケージに関連するコードのみを分析するアナライザーを供給できます。これは、パッケージのユーザーがパッケージの API を正しく使用する助けとなります。
アナライザーとソースジェネレーターの合計実行時間や、各アナライザーまたはソースジェネレーターの関連実行時間などの情報を表示するには、Preferences > Diagnostic Switches と移動し、EnableDomainReloadTimings を有効にしてください。これを有効にすると、コンソールウィンドウに情報が表示されます。
Unity は、NuGet を通じて直接 Roslyn アナライザーやソースジェネレーターをインストールすることをサポートしていません。以下の例は、ErrorProne.NET.CoreAnalyzers ライブラリを使用して、NuGet から Roslyn アナライザーとソースジェネレーターをインストールする方法を表します。
ErrorProne.NET.Core.dll
、ErrorProne.Net.CoreAnalyzers.dll
、RuntimeContracts.dll
です。Unity は RoslynAnalyzer ラベルを認識し、このラベルが付いたアセットを Roslyn アナライザーまたはソースジェネレーターとして扱います。アナライザーにこのラベルを割り当てると、Unity はアナライザーのスコープ内のスクリプトを再コンパイルし、アナライザーの規則に従ってそれらのスクリプトのコードを分析します。アナライザーと同じアセンブリ定義内にあるスクリプトは、そのアナライザーのスコープに含まれます。Assets フォルダーのルートレベルにあるアナライザーの場合、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 のドキュメント ルールセットをカスタマイズする を参照してください。
Assets
ルートフォルダーに、Default.ruleset
という名前のルールセットファイルを置きます。Default.ruleset
で定義する規則は、すべての定義済みアセンブリ (例えば、Assembly-CSharp.dll
)、および .asmdef
ファイルを使用して構築されたすべてのアセンブリに適用されます。
Default.ruleset の規則を定義済みのアセンブリにオーバーライドするには、ルートフォルダーに .ruleset ファイルを作成し、 [PredefinedAssemblyName].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 でルールセットファイルをテストするには、以下を行います。
RethrowError.cs
の複製を保存します。<?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
ファイルでは、以下の規則が定義されています。
プロジェクトにルールセットファイルを追加した後、規則を適用するアセンブリ内にあるスクリプトをすべて再インポートします。これを行うと、Unity は新しいルールセットファイルを使用してアセンブリを再コンパイルします。再コンパイルの後、コンソールウィンドウに以下の 2 つのメッセージが表示されます。
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.cs
と Assets/Subfolder/RethrowError.cs
の両方に適用していることに注目してください。
Assets/Subfolder に .ruleset ファイルを作成し、任意の名前を付けます (この例では Hello.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
ファイルは、Unity に EPC12 と ERP021 の両方を警告やエラーとして扱わずに、コンソールに出力するように指示します。
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 リポジトリへのリンクです。