Unityで[SerializeField]を使った時に出る未初期化の警告を消す

(2021/6/13追記) Unity対応済み

問題

Unity(2019.3.0f1)で[SerializeFiled]を使用してインスペクタから値を設定した場合

warning CS0649: ... is never assigned to, ...

の警告が出る

(一時的な)解決方法

Assets/csc.rspファイルを作る(C# Compiler Response File)
中身は

/nowarn:0649

もしくは

-nowarn:0649

すべてのコンパイル オプションは、-option および /option という 2 つの形で使用できます。 C# コンパイラ オプション | Microsoft Docs

根本的な解決はUnityが対応するまで待つしかない

一連の経緯

  1. Monoコンパイラのバグで今まで警告がでてなかった
  2. UnityがMonoからRoslynを使うようになった
  3. 警告が出るようになった
  4. Roslynにプログラマブルに警告抑える機能が追加される
    DiagnosticSuppressor APIを実装したので警告消すのは可能になった
    今まではなかった
    Programmatic suppression of warnings · Issue #30172 · dotnet/roslyn · GitHub
  5. Unity対応中(イマココ)

    This can be fixed using DiagnosticSuppressor API in Roslyn. However, this requires that Unity updates Roslyn to a newer version that supports DiagnosticSuppressor and that proper support for using Roslyn analyzers is added to Unity. The fix of this issue is therefore postponed.

[Feature Request] Use new DiagnosticSuppressor API to suppress CS0649 on SerializeField - Unity Forum
Unity Issue Tracker - [SerializedField] fields produce "Field is never assigned to..." warning

その他の方法

csc.rsp以外にも解決方法はあるものの自分は採用しなかったメモ

1. #pragmaを使う

#pragma warning disable 0649
// your code
#pragma warning restore 0649

これかcsc.rspで迷った

#pragmaの場合
一時的な対応: 全部の[SerializeField]を#pragmaで囲う
Unity対応後: #pragma書いたとこ全部消す

csc.rspの場合
一時的な対応: csc.rspファイル書くだけ
Unity対応後: csc.rspファイル消すだけ

csc.rspは他の部分の0649警告も全て消してしまうという欠点はあるけど,上記の手軽さから使うことにした

2. 初期値を書く

初期値を書く場合
一時的な対応: 全部の[SerializeField]部分に初期値を書く
Unity対応後: 特に何もしなくていい

採用しない理由
[SerializeField]を使う場合,プログラマーはその値がインスペクタで設定されることを想定している.
つまり初期値として,インスペクタの値が入っていることを想定している.
にもかかわらずコード上で,初期値としてnullや0を与えるというのは「インスペクタの値を初期値と想定する」というプログラマーの意図に反する.

初期値を使う時というのは,例えばインスペクタで値を設定することを主としているが, 「インスペクタで設定しない時はこの値で実行するつもり」,という意図があるときだけである.

最初からインスペクタでしか設定するつもりがないのならば,初期値は使わないほうがよい(その方が意図が明確になる)

(補足)
しかし,例えばUnityの公式サンプルでは初期値を与えて警告を消していたりする.
Unity 2D tools for game dev – evolved for optimal graphics performance
これはサンプルという性質上,Unity対応後にcsc.rspを消す方が手間なので理解できる.

3. publicにする

論外
[SerializeField] privateは「エディタ上では変更されることを想定しているが,実行時は外部から変更されない」ということを意図する時に使う.
publicにしたら実行時も外部から変更できてしまうのでコードの文脈が変わる.