しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Unity で Roslyn を使ってコード生成する

※ これは 2023/09/07 時点の Unity 2023.1.12f1 の情報です

最新版では動作が異なる可能性がありますのでご注意ください

前回で React のチュートリアルがひと段落して何をやるかまだ考えてなかったので、Unity の Roslyn を使ったコード生成を調べてみる

とりあえず適当な定数を持つクラスのソースコードを出力させる

まずコードの出力先となる適当な Unity プロジェクトを新規作成

UnityEditor が開いたら コード生成の .dll ファイル出力先として Assets/Pluginsディレクトリだけ作成しておく

その後、コード生成用の C# プロジェクトを作成するため、VSCode を開いてターミナルから下記コマンド実行

dotnet new console -o "SourceGenerator"

` プロジェクトが作成されたらProgram.csは使わないので削除して、SourceGenerator.csproj` を開く

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

上記の設定ファイルを下記のように書き換える

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis" Version="3.8.0" />
  </ItemGroup>

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Copy SourceFiles="$(TargetDir)$(TargetName).dll" DestinationFolder="../Roslyn/Assets/Plugins" />
  </Target>

</Project>

TargetFramework を .NET Standard2.0 にして、CodeAnalysis のライブラリ追加、ビルドした .dll を先ほどの Unity プロジェクトの Assets/Plugins にコピーする設定にするのがポイント

さっそく適当なコードを生成する SourceGenerator.cs を下記のように記述

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Text;

namespace SourceGenerator
{
    [Generator]
    public class CodeGenerator : ISourceGenerator
    {
        /// <inheritdoc/>
        public void Initialize(GeneratorInitializationContext context)
        {
        }

        private const string Code = @"using System;

namespace Sample
{
    public static class Constants
    {
        /// <summary>
        /// HogeHoge
        /// </summary>
        public const string Hoge = @""hogehoge"";
    }
}";

        /// <inheritdoc/>
        public void Execute(GeneratorExecutionContext context)
        {
            context.AddSource("Constants.g.cs", SourceText.From(Code, Encoding.UTF8));
        }
    }
}

ISourceGenerator のインターフェースを実装し、Initialize()Execute() のメソッドを追加

Constants.g.cs という単純な定数だけを持つクラスのソースコードを出力するように記述

VSCode のソリューションエクスプローラーの右クリックメニューから「リビルド」実行

すると Unity プロジェクトの Assets/Plugins/SourceGenerator.dll が出力されるので、選択し Inspector 上で下記のように設定し Apply

Asset LabelsRoslynAnalizer を指定しないと Roslyn によるコード生成が実行されない

このコード生成はソースファイルを出力しないので、試しに Unity プロジェクトの方で Script ファイルを作成して VSCode のインテリセンスを使ってみると⋯

なんか警告出てるけどちゃんと生成はされたっぽい