コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】UnitGenerator の基本的な使い方

はじめに

この記事では UnitGenerator の基本的な使い方を紹介していきます

目次

検証環境

  • Unity 2020.3.13f1
  • UnitGenerator 1.0.0

使い方

f:id:baba_s:20210719144334p:plain

Unity プロジェクト直下に「UnitSourceGen」フォルダを作成して

f:id:baba_s:20210719144337p:plain

そのフォルダ内に「UnitSourceGen.csproj」を作成して

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>..\Assets\Scripts\Generated</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="UnitGenerator" Version="1.0.0" />
        <Compile Include="..\Assets\Scripts\Models\*.cs" />
    </ItemGroup>
</Project>

上記の内容を書き込んで保存したら

dotnet build UnitSourceGen.csproj

上記のコマンドを実行します

f:id:baba_s:20210719144611p:plain

すると、「UnitSourceGen.csproj」の「CompilerGeneratedFilesOutputPath」に指定したパスに
「UnitOfAttribute.cs」が作成されます

f:id:baba_s:20210719144730p:plain

そうしたら「UnitSourceGen.csproj」の「Compile Include」に指定したパス、
「Assets/Scripts/Models」フォルダを作成して「CardId.cs」を作成して

using UnitGenerator;

namespace MyProject
{
    [UnitOf( typeof( int ) )]
    public readonly partial struct CardId
    {
    }
}

上記の内容を書き込んで保存し、

dotnet build UnitSourceGen.csproj

もう一度上記のコマンドを実行します

f:id:baba_s:20210719144938p:plain

これで「MyProject.CardId.Generated.cs」が作成されて
CardId を Value Object として扱いやすくするための機能が partial で定義されて

// コンストラクタ
var cardId = new CardId( 25 );

コンストラクタが使えるようになったり

// 変換演算子
var cardId = ( CardId ) 25;
var i      = ( int ) cardId;

int との変換ができるようになったり

// 等値演算子
var cardId1 = ( CardId ) 25;
var cardId2 = ( CardId ) 151;

if ( cardId1 == cardId2 )
{
}

if ( cardId1 != cardId2 )
{
}

2つの CardId が等しいかどうかを記述できるようになります

自動生成される機能は UnitOfAttribute に指定する UnitGenerateOptions で変更できます

詳しくは上記の README が参考になります

トラブルシューティング

  • 自分の環境だと UnitGenerator 1.2.0 だと dotnet build した時に
    XXXX.Generated が生成されなかった
    • UnitGenerator 1.0.0 を使用したら正常に生成された
  • 対象の構造体を名前空間に入れていないと dotnet build した時に
    生成されるファイルの名前が「.CardId.Generated」のようになるが、
    Unity は「.」から始まるファイルは無視されるので使用できなかった
    • 対象の構造体を名前空間に入れたら正常に認識された
  • 「UnitSourceGen.csproj」を「UnitGenerator.csproj」にしていたら
    名前が競合して dotnet build が正常に動作しなかった
    • 「UnitSourceGen.csproj」という名前なら正常に dotnet build できた

参考サイト様