※ お金のボーナスの話じゃないです。
問題: SerializeField と null 許容参照型
Unity で null 許容参照型を有効にしている環境で、SerializeField に対して null 免除演算子を使っていたらレビューコメントがつきました。
[SerializeField] GameObject Target = null!;
void Awake()
{
Assert.IsNotNull(Target);
}
null 免除演算子を使うことがいけないらしいです。個人的にはアプリケーション境界なのでアサーションして非 null として扱うのが妥当だと思ってコーディングしてました。こうすると参照設定が必須であることが宣言時にわかりますね。
ありがちな対応: フィールドを nullable にする
しょうがないのて nullable に変えました。
[SerializeField] GameObject? Target;
void Foo()
{
Assert.IsNotNull(Target);
Debug.Log(Target.name);
}
これなら文句はないでしょう。しかし参照設定エラーが、機能の実行時に発覚するのでは遅いですね。
改善: Required 属性 + ソースジェネレーター
Awake のアサーションはあったほうがいいですよね。nullable にするだけの変更が気に入らなかったので改善してやりました。つまり Awake のアサーションをソースジェネレーター化しました。
partial class FooBar
{
[Required, SerializeField] GameObject? Target;
}
上のように書くと次のコードを生成します。
partial class FooBar
{
void Awake()
{
AssertRequiredFields();
}
void AssertRequiredFields()
{
Assert.IsNotNull(Target);
}
}
Required 属性をみつけて、それが MonoBehaviour の派生型なら Awake と AssertRequiredFields の定義を追加します。
ここで Required は自作の属性でタグとしてだけ機能します。
面倒な Awake の記述を省略できました! ユーザーが Awake メソッドを定義している場合は Awake の定義を省略します。その場合は AssertRequiredFields を使ってアサーションします。
ボーナス: 参照設定をビルド時に保証できるようになった話
という機能だったんですが、Required 属性を作ったのでもっと何かできないかと AI ちゃんと相談してました。すると「ビルド時に参照の設定を保証する」という機能が手に入りました。Unity を使うのは数年ぶりですが、昔に欲しいと思っていた機能が思いがけず手に入りました。AI すごいですね。
ところでアセットストアの Odin でもできるかもしれません。予算がでるところなら買って解決していいと思います。DDD でいうところの一般的な業務領域ですね。
AI エージェントにプロンプトすれば AI ちゃんが実装してくれるのでコードは省略します。