⚙️

[SerializeField] の命名規約をソリューションごとに変更する

2024/03/23に公開

はじめに

C# のコーディング規約として、.NET ランタイムチームのコーディングスタイル規則を元にしたものがMicrosoft の公式ドキュメントに定義されており、その中に「private なインスタンスフィールドはアンダースコアをプレフィックスにする」と言うものがあります。

プライベート インスタンス フィールドはアンダースコア (_) で始まり、残りのテキストはキャメルケースになります。

また、public なインスタンスフィールドは宣言すべきではないと言ったニュアンスの記述もあり、事実上インスタンスフィールドはアンダースコアプレフィックスな private フィールドが大半になると思います。

一般に、フィールドに対する private または protected のアクセシビリティを宣言する必要があります。 型からクライアント コードに公開するデータは、メソッド、プロパティ、インデクサーを使用して提供する必要があります。 これらの構成要素を使用して、内部フィールドに間接的にアクセスすることで、無効な値が入力されることを防止できます。 パブリック プロパティによって公開されるデータを格納するプライベート フィールドは、バッキング ストアまたはバッキング フィールドと呼ばれます。 public フィールドを宣言することもできますが、その場合、その型を使うコードで、そのフィールドを不正な値に設定することや、オブジェクトのデータを変更することを防ぐことができません。

しかしながら、Unity に於ける [SerializeField] なフィールドは Unity 公式のコンポーネントですらアンダースコアの有無が揺れており、アクセス可視性も揺れていることなどもあり、プロジェクトによってまちまちという状況ではないかと思います。

class Foo
{
    private int _hoge;
}

class Bar : MonoBehaviour
{
    [SerializeField] private int _fuga;
    [SerializeField] private int piyo;
    // Unity の仕様上、public フィールドも Serializable なので利用しているケースも多そう
    public int ponyo;
}

JetBrains Rider に於けるインスペクション

筆者は .NET や Unity の開発に JetBrains Rider を利用しているのですが、Rider には各種名称がルールに従っているかどうか?をチェックする機能があります。


private instance field はアンダースコア始まり

method は Pascal Case

このインスペクションに於いて、Unity の SerializeField は C# のコーディングルールと乖離することが多いことから、例外的に設定を上書きできるようになっています。


SerializeField 用の設定

この機能を利用することで、「SerializeField はアンダースコアプレフィックスなし」としたい場合や「m_ をプレフィックスとする」といった対応が可能になります


設定前は警告が出る

プレフィックスなしに設定

設定後は警告が消える

プロジェクト(ソリューション)毎の設定

SerializeField の命名規約問題について、基本的には上述の設定を変えておくだけで OK です。
が、例えば「個人プロジェクトはアンダースコアありで、業務プロジェクトはアンダースコアなし」といった具合にプロジェクト毎にルールが異なる場合、プロジェクトを開く度に設定を変更する必要があり結構面倒です。
で、本稿の本題は、これをどうにかする方法を見つけたよ、と言うお話です。(相変わらず前置きが長い…w)

プロジェクト毎のコーディングルール設定と言うと EditorConfig (.editorconfig) が思い当たりますが、「Unity の SerializeField 用の命名規約」は Rider(というか ReSharper)の機能であって EditorConfig の機能ではないため、「.editorconfig に定義してリポジトリに置いておく」作戦は使えません。
Rider(というか ReSharper)の設定を上書きしたい場合、レイヤーベースの設定という機能を利用することで実現できます。

「レイヤーベースの設定」機能とは、その名の通り設定に階層構造を持たせるための機能で、既定では「コンピュータ」→「ソリューションチーム共有」→「ソリューションパーソナル」の粒度で設定値を上書きできる仕組みとなっています。

この仕組みを利用することで、「コンピュータ全体の設定としてはアンダースコアありだが、このプロジェクト(ソリューション)はアンダースコアなしとする」といった設定の上書きができるようになります。

設定方法は大まかに2通りのやり方があります。

保存時に変更点の保存先レイヤーを選択


team-shared なレイヤーに保存

設定保存時に保存先レイヤーを選択する場合、任意の変更(今回で言えば Serialized Field Naming Rules の Prefix を _ から空文字に変更)を保存する際に、Save ボタンの右側にあるプルダウンを押下し、目的の保存先レイヤー(Solution "<SolutionName>" team-shared など)を選択するだけで OK です。

レイヤー管理画面から設定を変更


Settings ウィンドウ左下に Manage Layers ボタンがある

Settings 画面を開き、左下にある Manage Layers ボタンを押下します。


設定レイヤー画面から設定変更

表示される Preferences Layers ウィンドウに一覧されるレイヤーから目的のレイヤー(今回で言うと Solution "Sample" team-shared)を選択し、左上にある 🔧 アイコンを押下します。


レイヤー設定可能な項目に絞り込まれる

レイヤー設定に対応した設定項目が絞り込まれた状態で Settings 画面が開くので、目的の設定変更を行い Save ボタンを押下します。

設定の保存場所

レイヤー設定した設定値は、それぞれのレイヤーに応じた場所に保存されます。

このコンピュータ」レイヤーはプラットフォームごとに以下のファイルに保存されます。

Platform Path
Windows %APPDATA%\JetBrains\Rider2023.3\resharper-host\GlobalSettingsStorage.DotSettings
macOS ~/Library/Application Support/JetBrains/Rider2023.3/resharper-host/GlobalSettingsStorage.DotSettings
Linux ~/.Rider2023.3/config/resharper-host/GlobalSettingsStorage.DotSettings

ソリューションチーム共有」レイヤーは、.sln ファイルと同階層の <SolutionName>.sln.DotSettings というファイルに保存されます。
このファイルは Git などのバージョン管理システムの管理下に置くべきです。

ソリューションパーソナル」レイヤーは、.sln ファイルと同階層の <SolutionName>.sln.DotSettings.user というファイルに保存されます。
このファイルはバージョン管理すべきではありません。
チーム共有レイヤーに設定を施したにも関わらず、反映されない場合はパーソナルレイヤーで上書きしている可能性があるのでチェックしてみると良いかもです。

まとめ

長々と綴りましたが、本稿を一言でまとめると「Rider (ReSharper) のレイヤーベース設定をうまく活用しましょう」というお話でした。
適切にバージョン管理すればプロジェクトのコーディングルールなどをプロジェクトメンバーに共有することができるので、コードレビューの手間を減らすことができるかもしれません。

Rider (ReSharper) はいいぞ!

Discussion