UnityでC#スクリプトを書いていると、「変数がInspectorに表示されない…」と悩んだことはありませんか?
あるいは「とりあえず public
にすれば見えるからOK」と思っていませんか?
でもちょっと待ってください。public
と [SerializeField]
には、明確な違いと、それぞれに適した使い分け方があります。
この記事では、Unity初心者がつまづきやすいこの2つの違いをわかりやすく解説しつつ、実際の開発でどう使い分けるべきかを紹介していきます。
結論から言うと…
public
:外部のスクリプトからもアクセスできる(インスペクターに表示される)[SerializeField] private
:インスペクターには表示されるが、外部からはアクセスできない
つまり、「見せたいけど触らせたくない」なら [SerializeField]
を使うべきというのが基本ルールです。
例で見る違い
public class Example : MonoBehaviour
{
public int publicValue = 10;
[SerializeField] private int serializedValue = 20;
private int hiddenValue = 30;
}
このコードをUnityで確認すると、Inspectorには publicValue
と serializedValue
が表示され、hiddenValue
は表示されません。
変数名 | Inspectorに表示 | 外部からアクセス |
---|---|---|
publicValue | ◯ | ◯ |
serializedValue | ◯ | ✕ |
hiddenValue | ✕ | ✕ |
つまり、[SerializeField]
は「インスペクター用の例外公開」と考えると分かりやすいです。
理解を深める
そもそもSerializeとは何か?
Unityの「Inspectorに表示されるかどうか」は、「その変数がシリアライズ(保存)されるかどうか」にかかっています。
[SerializeField]
は、その変数をシーンやプレハブに保存できるようにマークする属性です。
これがあると、Unityのシリアライザ(保存システム)がその変数を認識し、インスペクターに表示してくれるという仕組みです。
なぜpublicばかり使うのはよくないのか?
public
にすると、他のスクリプトからその変数に自由にアクセスできてしまいます。
enemy.health = 0; // 外部から直接書き換え
これは便利な反面、設計の意図に反して勝手に書き換えられる危険性を含んでいます。
特に規模が大きくなってくると、「どこで値が変わったのかわからない」状態が頻発するようになります。
そうならないように、必要最低限の場所にだけアクセスを許可する設計(カプセル化)が大切なのです。
おすすめの使い分けルール
次のような基準で使い分けると、バグも減ってコードが読みやすくなります。
- ゲームのデザイナーや自分自身がInspectorで調整したい変数:
[SerializeField] private
- 他のスクリプトからアクセスされるべき値:
public
(もしくはプロパティを使う) - 完全に内部処理にしか使わない値:
private
(非表示)
さらに一歩進んで、public
の代わりに public { get; private set; }
のようなプロパティを使うことで、読み取り専用にする設計もよく使われます。
👇 実際の現場ではこうしてます
public class Player : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
public float MoveSpeed => moveSpeed; // 読み取り専用で公開
}
=>
は「矢印演算子」とも呼ばれる書き方で、「moveSpeedを返すだけ」の処理を簡潔に書いているだけです。
このように、「編集はInspectorから」「読み取りは他スクリプトから」という2つのニーズを分ける設計が非常に有効です。
まとめ:SerializeFieldとpublicの違い、しっかり使い分けよう
public
はインスペクターに表示され、外部からもアクセス可能[SerializeField] private
はインスペクターにだけ表示され、外部からは触れない- デバッグやバランス調整がしやすく、意図しない書き換えを防げる設計になる
「とりあえず public」ではなく、「誰がどこからその値を触るべきか」を考えることが、より安全でスマートなコードの第一歩です。