Unityでasmdefを適用しつつC#10の機能を使う
Unityで最新のC#機能を使う方法(C# 10/11以降)
Unityの公式C#サポートは現在C# 9.0までですが、C# 10や11には便利な機能があります。
Unity 2022.2以降には新しいC#コンパイラがすでに入っていて、設定を変えるだけでこれらの新機能を使えるようになります。
Unityとコードエディタの両方の設定
新しいC#バージョンをUnityで使うには、2つの場所で設定を変える必要があります。
- Unityエディタのコンパイラ: Unityがゲームをビルドしたり動かしたりするときにコードをチェックする部分です。
- コードエディタ(Visual Studio Codeなど): コードを書くときに使うソフトです。コードの入力補助やエラー表示をしてくれます。
この2つの設定が合っていないと、Unityでは動くのにVSCodeではエラーが出るといったことが起きます。
csc.rsp
)
ステップ1: UnityのコンパイラをC# 10にする (まずは、UnityにC# 10を使うように指示します。これにはcsc.rsp
というファイルを使います。
.asmdef
ファイルを使っている場合
もし.asmdef
(アセンブリ定義ファイル)を使ってコードを分けているなら、それぞれの.asmdef
があるフォルダに設定が必要です。
C# 10の機能を使いたいアセンブリのフォルダ(.asmdef
ファイルがある場所)に、csc.rsp
という名前のファイルを作り、次の1行を書き込みます。
-langVersion:10
例えば、Assets/Scripts/MyGame/Core
というフォルダにCore.asmdef
があるなら、Assets/Scripts/MyGame/Core/csc.rsp
を作ります。これを、C# 10を使いたいアセンブリの数だけ繰り返します。
CsprojModifier
)
ステップ2: コードエディタもC# 10にする (次に、VSCodeのようなコードエディタがコードを正しく理解できるように設定します。この作業を自動でやってくれる便利なツールCsprojModifierを使います。
1. CsprojModifierを入れる
UnityのPackage Managerを開き、以下のURLからパッケージをインストールします。
https://github.com/Cysharp/CsprojModifier.git?path=src/CsprojModifier/Assets/CsprojModifier
LangVersion.props
ファイルを作る
2. Unityプロジェクトのルートフォルダに、LangVersion.props
という名前のファイルを作り、以下の内容を書き込みます。
<Nullable>enable</Nullable>
も一緒に入れておくと、C# 8.0以降で使えるNull許容参照型が有効になります。
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
3. CsprojModifierを設定する
Unityエディタで Project Settings > Editor > C# Project Modifier
を開きます。
-
Additional project imports:
- 「+」ボタンを押して、パスに
LangVersion.props
と入力します。
- 「+」ボタンを押して、パスに
-
The project to be added for Import.:
-
.asmdef
を使っている場合、C# 10を使いたいすべてのアセンブリの.csproj
ファイル名をここに追加します。例えば、Core.asmdef
があるならCore.csproj
をリストに入れます。
-
設定が終わったら、ウィンドウの下にあるRegenerate project filesボタンを押して、変更を反映させます。
IsExternalInit
)
ステップ3: C# 9.0の互換性対策 (C# 9.0で追加されたinit
セッター(一度だけ値を設定できる機能)やrecord
型(データ構造を簡単に作れる機能)を使うには、System.Runtime.CompilerServices.IsExternalInit
という特別な型が必要です。Unityが使っている古い.NETバージョンにはこれが含まれていないため、自分で用意する必要があります。
なぜ複数のファイルが必要なのか?
このIsExternalInit
クラスをinternal
で定義した場合、その定義は同じアセンブリの中でしか有効になりません。そのため、C# 9.0以降の機能を使いたいすべてのアセンブリに、このクラスのファイルを置く必要があります。
次の内容でIsExternalInit.cs
というファイルを作り、必要なアセンブリのフォルダにそれぞれ置きます。
namespace System.Runtime.CompilerServices
{
/// <summary>
/// C# 9.0 の init; や record 型を、古い .NET バージョンで利用するために必要な型。
/// このクラスをプロジェクトに追加することで、CS0518 エラーを回避できます。
/// </summary>
internal static class IsExternalInit
{
}
}
問題と解決策
FileNotFoundException
/ DirectoryNotFoundException
が出る
CsprojModifierがLangVersion.props
を見つけられないというエラーです。
- 原因: CsprojModifierの設定で指定したパスと、ファイルの実際の場所が違っています。
-
解決策:
LangVersion.props
ファイルがプロジェクトの一番上のフォルダに正しく置かれているか確認し、CsprojModifierの設定ではパスを「LangVersion.props
」とだけ入力してください。
CS8773: Feature '...' is not available in C# 9.0.
が出る
このエラーは、どこで出ているかによって原因が異なります。
-
VSCodeなどのコードエディタだけで出る場合:
CsprojModifier
の設定ミスです。C# 10を使いたい.csproj
ファイルが設定リストに追加されているか、LangVersion.props
が正しく読み込まれているか確認してください。 -
Unityエディタのコンソールで出る場合:
csc.rsp
ファイルの設定漏れです。エラーが出ているアセンブリの.asmdef
ファイルと同じフォルダに、-langVersion:10
と書かれたcsc.rsp
ファイルが置かれているか確認してください。
まとめ
Unityで最新のC#機能を使うには、次の3つの設定が必要です。
-
csc.rsp
: Unityが使うC#のバージョンをC# 10にする。 -
CsprojModifier
+LangVersion.props
: コードエディタが使うC#のバージョンをC# 10にする。 -
IsExternalInit.cs
: C# 9.0のinit
やrecord
型を古い.NET環境で使えるようにする。
これらの設定を行うことで、Unityでも最新のC#機能を使った効率的な開発が可能になります。
参考
Discussion