Unity 6でプロパティはインスペクタに表示される? ― [field: SerializeField]と2つの書き方
C#を学んでからUnityに入ると、「変数はプロパティにしましょう」と教わったのに、プロパティにした途端インスペクタから項目が消えてしまい、戸惑うことがあります。
この記事では、2026年9月時点の最新版であるUnity 6.6(6000.6系)で、C#のプロパティがインスペクタに表示されるのかどうかを、公式ドキュメントに沿って整理します。
結論:プロパティそのものは表示されない
Unity 6.6でも、C#のプロパティそのものはインスペクタに表示されません。
Unityのシリアライズ(値の保存)の仕組みは、クラスのフィールドを直接対象にしています。プロパティは対象外です。インスペクタに表示されるのは「シリアライズされたフィールド」なので、次のようなプロパティは表示されません。
using UnityEngine;
public class Player : MonoBehaviour
{
// フィールド:インスペクタに表示される
public int attack = 10;
// プロパティ:インスペクタに表示されない
public int Hp { get; set; } = 100;
}
ただし、プロパティの「中身」を保存しているフィールド(バッキングフィールド)をシリアライズすれば、インスペクタで値を設定できます。方法は2つあります。
方法1:自動実装プロパティに[field: SerializeField]を付ける
{ get; set; } と書く自動実装プロパティでは、コンパイラが見えないバッキングフィールドを自動で作ります。field: を付けて属性を書くと、そのバッキングフィールドに属性を付けられます。
using UnityEngine;
public class Player : MonoBehaviour
{
[field: SerializeField]
public int Hp { get; private set; } = 100;
}
これでインスペクタに「Hp」という項目が表示され、値を設定できるようになります。
private set と組み合わせるのがポイントです。
- インスペクタからは値を編集できる
- ほかのスクリプトからは読み取りだけできる(勝手に書き換えられない)
「インスペクタで初期値を決めたいが、ほかのクラスからは変更させたくない」という、Unityでよくある要望を1行で書けます。詳しい使い方は Unityのプロパティをもっとスッキリ書く![field: SerializeField]の使い方 でも解説しています。
方法2:バッキングフィールドを自分で書く
昔からある書き方です。[SerializeField] を付けたprivateフィールドを用意し、プロパティから読み書きします。
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField, Range(0, 999)]
private int hp = 100;
public int Hp
{
get => hp;
private set => hp = Mathf.Clamp(value, 0, 999);
}
}
コードは長くなりますが、次のような利点があります。
[Range]などの属性をフィールドに素直に付けられる- フィールド名を自分で決めるので、後述する「名前変更で値が消える」問題が起きにくい
2つの方法の比較
| 方法1:[field: SerializeField] | 方法2:自分でフィールドを書く | |
|---|---|---|
| コードの長さ | 短い(1行) | 長い |
| インスペクタでの表示名 | プロパティ名(Hp) | フィールド名(hpが「Hp」と表示される) |
| setterの処理 | 使えない(自動実装のため) | 書けるが、インスペクタからの変更では呼ばれない |
| 名前変更への強さ | 弱い(内部名が変わる) | 強い |
| 向いている場面 | 単純な設定値 | 値の制限や複雑な処理が必要なとき |
注意点1:インスペクタで変更してもsetterは呼ばれない
方法2でsetterに Mathf.Clamp を書きましたが、インスペクタで値を変更したときは、このsetterは通りません。インスペクタが書き換えるのはフィールドそのものだからです。
そのため、インスペクタで 5000 と入力すると、フィールドにはそのまま 5000 が入ってしまいます。インスペクタからの入力も制限したい場合は、次のどちらかを使います。
- フィールドに
[Range(0, 999)]などの属性を付ける(上のコード例のように) OnValidate()で値をチェックする
// インスペクタで値が変更されたときにエディタから呼ばれる
private void OnValidate()
{
hp = Mathf.Clamp(hp, 0, 999);
}
注意点2:名前を変えると設定した値が消えることがある
方法1で作られるバッキングフィールドの本当の名前は、<Hp>k__BackingField のような特殊な名前です。そのため、プロパティ名を Hp から Health に変えると内部の名前も変わり、インスペクタで設定済みの値が初期値に戻ってしまいます。
同じことは、publicフィールドを自動実装プロパティに書き換えたときにも起こります。値を引き継ぎたいときは [FormerlySerializedAs] に以前の名前を指定します。
using UnityEngine;
using UnityEngine.Serialization;
public class Player : MonoBehaviour
{
// 以前は public int hp; というフィールドだった場合
[field: SerializeField, FormerlySerializedAs("hp")]
public int Hp { get; private set; } = 100;
}
プロパティ名を変える場合は、以前の内部名 "<Hp>k__BackingField" を指定する必要があります。名前を頻繁に変える可能性があるなら、方法2のほうが安全です。
バッキングフィールドの仕組みそのものは、C# オートプロパティの裏側 ― コンパイラが生成するバッキングフィールドを覗いてみよう で詳しく紹介しています。
まとめ
- インスペクタに表示されるのはフィールドだけ。Unity 6.6でもプロパティそのものは表示されない
- 自動実装プロパティなら
[field: SerializeField]を付けるとインスペクタで設定できる private setと組み合わせると「インスペクタで設定、外部からは読み取りのみ」が簡単に書ける- インスペクタからの変更はsetterを通らないので、値の制限は
[Range]やOnValidate()で行う - 名前を変えると値が消えることがあるので、
[FormerlySerializedAs]で引き継ぐ
シリアライズの基本をもう少し広く知りたい方は、Unityにおけるシリアライズと[SerializeField]の活用・プロパティのシリアライズ対策 もあわせて読んでみてください。





![Unity 6.6で[field: SerializeField]を付けたプロパティがインスペクタに表示される様子](https://soft-rime.com/wp-content/uploads/2026/09/unity6-property-inspector-hyoji-150x150.png)





ディスカッション
コメント一覧
まだ、コメントがありません