Bird
Raised Fist0
Unityframework~15 mins

Public vs SerializeField in Unity - Trade-offs & Expert Analysis

Choose your learning style10 modes available
Overview - Public vs SerializeField
What is it?
In Unity, 'public' and '[SerializeField]' are ways to make variables visible and editable in the Unity Editor. A public variable is accessible from other scripts and shows up in the editor automatically. A private variable is hidden by default, but adding [SerializeField] makes it visible in the editor without allowing other scripts to access it directly. This helps control how data is shared and modified in your game objects.
Why it matters
Without controlling variable visibility, your game code can become messy and error-prone. Public variables expose data to all scripts, which can lead to unintended changes and bugs. Using [SerializeField] lets you keep variables private but still tweak them in the editor, making your code safer and easier to maintain. Without these tools, managing game data would be confusing and risky.
Where it fits
Before learning this, you should understand basic C# variables and access modifiers like public and private. After this, you can learn about Unity's Inspector, encapsulation, and best practices for organizing game data and scripts.
Mental Model
Core Idea
Public makes variables accessible everywhere and visible in the editor, while [SerializeField] keeps variables private but still editable in the editor.
Think of it like...
Think of a public variable like a glass door: anyone can see inside and reach in to change things. A [SerializeField] private variable is like a locked display case: you can see and adjust what's inside through the glass, but you can't grab it directly.
┌───────────────┐       ┌───────────────────────────┐
│   Public Var  │──────▶│ Visible & Editable in Editor│
│ (accessible)  │       │ Accessible by other scripts │
└───────────────┘       └───────────────────────────┘

┌─────────────────────┐  ┌───────────────────────────────┐
│ Private Var (hidden) │  │ [SerializeField] Private Var   │
│ (not visible)        │  │ Visible & Editable in Editor   │
└─────────────────────┘  │ Not accessible by other scripts│
                         └───────────────────────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding Public Variables
🤔
Concept: Public variables are accessible from any other script and show up in the Unity Editor automatically.
In Unity, when you declare a variable as public, it becomes visible in the Inspector window. For example: public int health = 100; This means you can change 'health' in the editor and also access or modify it from other scripts freely.
Result
The variable appears in the Unity Editor and can be accessed or changed by any script.
Knowing that public variables are fully open helps you understand why they are easy to use but can lead to less controlled code.
2
FoundationPrivate Variables Are Hidden
🤔
Concept: Private variables are hidden from other scripts and the Unity Editor by default.
If you declare a variable as private, like: private int speed = 5; it won't show up in the Inspector, and other scripts cannot access it directly. This keeps the variable safe from outside changes.
Result
The variable is invisible in the editor and inaccessible from other scripts.
Understanding private variables helps you protect data inside a script, preventing accidental changes.
3
IntermediateUsing [SerializeField] to Show Private Variables
🤔Before reading on: do you think [SerializeField] makes a variable public or just visible in the editor? Commit to your answer.
Concept: [SerializeField] makes private variables visible and editable in the Unity Editor without making them accessible to other scripts.
You can write: [SerializeField] private int damage = 10; This shows 'damage' in the Inspector so you can tweak it, but other scripts cannot access it directly because it remains private.
Result
The variable is visible and editable in the editor but remains private in code.
Knowing this lets you keep your code safe while still using Unity's editor for easy adjustments.
4
IntermediateWhy Not Just Use Public Variables?
🤔Before reading on: do you think using only public variables is good practice or risky? Commit to your answer.
Concept: Using only public variables can cause bugs because any script can change them anytime, making your game harder to debug and maintain.
Public variables expose your data to all scripts. If many scripts change the same variable, it can cause unexpected behavior. Using private with [SerializeField] limits access and keeps control inside the script.
Result
Better code safety and easier debugging by limiting variable access.
Understanding the risks of public variables encourages better coding habits and more stable games.
5
AdvancedBalancing Editor Access and Code Safety
🤔Before reading on: do you think [SerializeField] affects runtime performance or just editor visibility? Commit to your answer.
Concept: [SerializeField] only affects editor visibility and serialization; it does not change runtime access or performance.
At runtime, private variables with [SerializeField] behave like normal private variables. The attribute only tells Unity to save and show them in the editor. This means you get editor convenience without runtime cost or exposure.
Result
Safe, efficient code with editable variables in the editor.
Knowing this helps you optimize your code structure without sacrificing editor usability.
6
ExpertSerialization and Unity's Inspector Internals
🤔Before reading on: do you think Unity serializes all variable types by default or only some? Commit to your answer.
Concept: Unity serializes only certain types and fields marked public or [SerializeField], using this data to save and display in the Inspector.
Unity's serialization system looks for public fields or private fields with [SerializeField] to save their values. It supports basic types, structs, and some classes but skips unsupported types. This system enables the Inspector to show and save variable values between play sessions.
Result
Variables marked correctly are saved and editable in the editor; others are ignored.
Understanding serialization internals explains why some variables don't appear or save, guiding better code design.
Under the Hood
Unity uses a serialization system that scans scripts for fields to save and display in the Inspector. Public fields and private fields with [SerializeField] are included. At compile time, Unity generates metadata to handle these fields, allowing the editor to read and write their values. At runtime, these fields behave normally according to their access modifiers. The serialization system excludes fields that are private without [SerializeField] or unsupported types.
Why designed this way?
Unity needed a way to let developers tweak variables in the editor without exposing all data publicly in code. Public variables were easy but unsafe. [SerializeField] was introduced to balance editor usability with encapsulation, improving code safety and maintainability. This design avoids breaking existing code while adding flexibility.
┌───────────────┐       ┌───────────────────────────────┐
│   Script      │       │ Unity Serialization System     │
│ ┌───────────┐ │       │ ┌───────────────────────────┐ │
│ │ public var│ │──────▶│ │ Includes public fields      │ │
│ └───────────┘ │       │ │ and [SerializeField] fields │ │
│ ┌───────────┐ │       │ └───────────────────────────┘ │
│ │private var│ │       │                               │
│ └───────────┘ │       │                               │
│ [SerializeField]│─────▶│                               │
└───────────────┘       └───────────────────────────────┘
          │
          ▼
┌───────────────────────────────┐
│ Inspector shows serialized vars│
│ Saves values between sessions  │
└───────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does making a variable public always mean it is visible in the Unity Editor? Commit yes or no.
Common Belief:Public variables are always visible and editable in the Unity Editor.
Tap to reveal reality
Reality:Public variables are visible in the editor only if they are of a serializable type. Some types like dictionaries or certain classes are not serialized and won't show up.
Why it matters:Assuming all public variables appear can cause confusion when variables don't show in the editor, leading to wasted debugging time.
Quick: Does [SerializeField] make a variable accessible from other scripts? Commit yes or no.
Common Belief:[SerializeField] makes a variable public and accessible from other scripts.
Tap to reveal reality
Reality:[SerializeField] only affects editor visibility and serialization; the variable remains private and inaccessible to other scripts.
Why it matters:Misunderstanding this can lead to incorrect assumptions about code access and security, causing bugs or design flaws.
Quick: Are private variables without [SerializeField] saved between play sessions? Commit yes or no.
Common Belief:Private variables are saved and visible in the editor even without [SerializeField].
Tap to reveal reality
Reality:Private variables without [SerializeField] are neither serialized nor visible in the editor, so their values reset between play sessions.
Why it matters:Expecting private variables to persist without serialization causes unexpected behavior and lost data.
Quick: Does using [SerializeField] affect runtime performance? Commit yes or no.
Common Belief:[SerializeField] slows down the game because it adds overhead at runtime.
Tap to reveal reality
Reality:[SerializeField] only affects editor serialization and has no impact on runtime performance.
Why it matters:Avoiding [SerializeField] due to false performance fears limits code safety and editor usability.
Expert Zone
1
Unity's serialization system does not serialize properties, only fields, so [SerializeField] cannot be applied to properties.
2
Certain types like events, dictionaries, and some custom classes are not serialized even if public or marked with [SerializeField], requiring custom serialization solutions.
3
Using [SerializeField] with private backing fields combined with public read-only properties allows safe data exposure with editor tweakability.
When NOT to use
Avoid using public variables when you want to protect data integrity; prefer private with [SerializeField]. Do not use [SerializeField] on unsupported types; instead, implement custom serialization or use ScriptableObjects for complex data.
Production Patterns
In professional Unity projects, developers use private variables with [SerializeField] to expose only necessary data in the editor, combined with public read-only properties or methods for controlled access. This pattern improves encapsulation and reduces bugs caused by unintended external modifications.
Connections
Encapsulation in Object-Oriented Programming
Public vs [SerializeField] is a Unity-specific way to implement encapsulation by controlling access and visibility.
Understanding encapsulation helps grasp why private variables with controlled editor exposure improve code safety and maintainability.
Data Binding in UI Frameworks
Both involve exposing internal data to an external interface for controlled editing or display.
Knowing how data binding separates data logic from UI helps understand why Unity separates code access from editor visibility.
Database Column Visibility and Access Control
Similar to controlling which database columns are visible or editable by users, Unity controls variable visibility and access.
This connection shows how access control principles apply across software domains, reinforcing the importance of controlled data exposure.
Common Pitfalls
#1Making all variables public to see them in the editor.
Wrong approach:public int score = 0; public float speed = 5f;
Correct approach:[SerializeField] private int score = 0; [SerializeField] private float speed = 5f;
Root cause:Confusing editor visibility with access control, leading to unsafe code.
#2Assuming [SerializeField] makes variables accessible from other scripts.
Wrong approach:[SerializeField] private int health = 100; // In another script: player.health = 50; // Error: 'health' is inaccessible due to protection level
Correct approach:[SerializeField] private int health = 100; // Provide a public method or property to access safely: public int Health => health;
Root cause:Misunderstanding the difference between editor serialization and code access modifiers.
#3Expecting private variables without [SerializeField] to appear in the editor or save values.
Wrong approach:private int lives = 3; // Not visible or saved in editor
Correct approach:[SerializeField] private int lives = 3; // Visible and saved in editor
Root cause:Not knowing that Unity only serializes public or [SerializeField] fields.
Key Takeaways
Public variables are visible in the Unity Editor and accessible from any script, which can lead to unsafe code if overused.
[SerializeField] allows private variables to be visible and editable in the editor without exposing them to other scripts, improving encapsulation.
Unity's serialization system only saves and shows public fields or private fields marked with [SerializeField], ignoring others.
Using [SerializeField] balances editor convenience with code safety, enabling better game development practices.
Understanding the difference between editor visibility and code access is essential to avoid bugs and write maintainable Unity scripts.

Practice

(1/5)
1. What is the main difference between a public variable and a [SerializeField] private variable in Unity?
easy
A. public variables are accessible by other scripts and visible in the Inspector, while [SerializeField] private variables are only visible in the Inspector but not accessible by other scripts.
B. public variables are hidden in the Inspector, but [SerializeField] private variables are accessible by all scripts.
C. public variables cannot be edited in the Inspector, but [SerializeField] private variables can be edited by other scripts.
D. public variables are only accessible inside the class, while [SerializeField] private variables are accessible everywhere.

Solution

  1. Step 1: Understand public variable behavior

    A public variable is accessible by all scripts and also visible in the Unity Inspector for editing.
  2. Step 2: Understand [SerializeField] with private

    A [SerializeField] private variable is hidden from other scripts but still visible and editable in the Inspector.
  3. Final Answer:

    public variables are accessible by other scripts and visible in the Inspector, while [SerializeField] private variables are only visible in the Inspector but not accessible by other scripts. -> Option A
  4. Quick Check:

    Access and visibility differ between public and [SerializeField] private [OK]
Hint: Public = accessible everywhere; SerializeField private = Inspector only [OK]
Common Mistakes:
  • Thinking SerializeField makes variable public
  • Assuming public variables are hidden in Inspector
  • Confusing private and public accessibility
2. Which of the following is the correct way to make a private variable visible in the Unity Inspector?
easy
A. private int score; [SerializeField]
B. [SerializeField] private int score;
C. public [SerializeField] int score;
D. int [SerializeField] private score;

Solution

  1. Step 1: Recall correct attribute placement

    The [SerializeField] attribute must be placed before the variable declaration.
  2. Step 2: Check variable declaration syntax

    The correct syntax is [SerializeField] private int score; to make a private variable visible in Inspector.
  3. Final Answer:

    [SerializeField] private int score; -> Option B
  4. Quick Check:

    Attribute before private variable declaration [OK]
Hint: Put [SerializeField] before private variable declaration [OK]
Common Mistakes:
  • Placing [SerializeField] after variable
  • Mixing public and [SerializeField] incorrectly
  • Wrong order of keywords
3. Consider this Unity C# script snippet:
public class Player : MonoBehaviour {
    [SerializeField] private int health = 100;
    public int score = 0;

    void Start() {
        Debug.Log(health);
        Debug.Log(score);
    }
}
What will be printed in the Unity Console when the game starts?
medium
A. Error: health is private and cannot be accessed
B. 0 and 100
C. 100 and 0
D. Nothing will print

Solution

  1. Step 1: Understand variable values and accessibility

    The private variable health is serialized and initialized to 100, so it is accessible inside the class and prints 100. The public variable score is initialized to 0 and prints 0.
  2. Step 2: Check Debug.Log outputs

    Both Debug.Log(health) and Debug.Log(score) print their current values: 100 and 0 respectively.
  3. Final Answer:

    100 and 0 -> Option C
  4. Quick Check:

    Private serialized variables accessible inside class [OK]
Hint: Private serialized variables print normally inside class [OK]
Common Mistakes:
  • Thinking private variables can't be accessed inside class
  • Confusing initialization values
  • Assuming serialization affects runtime access
4. You have this code in Unity:
public class Enemy : MonoBehaviour {
    [SerializeField] private int damage = 10;
}
But in the Inspector, the damage value stays at 0 even after you press Play. What is the likely problem?
medium
A. The damage variable is private and cannot be changed at runtime.
B. The [SerializeField] attribute is only for public variables.
C. You forgot to make damage public to change it in code.
D. The Inspector value overrides the code assignment, so damage stays at 0.

Solution

  1. Step 1: Understand Inspector and code value interaction

    If a serialized field has a value set in the Inspector, Unity uses that value at runtime, overriding the code default initialization.
  2. Step 2: Explain why damage stays 0

    The Inspector value for damage is 0, so even though code initializes it to 10, the Inspector value overrides it.
  3. Final Answer:

    The Inspector value overrides the code assignment, so damage stays at 0. -> Option D
  4. Quick Check:

    Inspector values override code assignments at runtime [OK]
Hint: Inspector values override code assignments on serialized fields [OK]
Common Mistakes:
  • Assuming private variables can't be changed in code
  • Thinking [SerializeField] only works on public variables
  • Ignoring Inspector value overrides
5. You want to keep a variable speed editable in the Unity Inspector but prevent other scripts from modifying it directly. Which is the best way to declare it?
hard
A. [SerializeField] private float speed;
B. private float speed; // no attribute
C. public float speed;
D. public float speed { get; private set; }

Solution

  1. Step 1: Identify requirement for Inspector editing and script protection

    The variable must be editable in Inspector but not accessible publicly by other scripts.
  2. Step 2: Evaluate options

    public float speed; makes it public, so other scripts can modify it. private float speed; // no attribute hides it from Inspector. [SerializeField] private float speed; uses [SerializeField] with private, making it editable in Inspector but hidden from other scripts. public float speed { get; private set; } uses a public property with private setter, which is not visible in Inspector by default.
  3. Final Answer:

    [SerializeField] private float speed; -> Option A
  4. Quick Check:

    SerializeField + private = Inspector editable, script protected [OK]
Hint: Use [SerializeField] private for Inspector edit, no public access [OK]
Common Mistakes:
  • Making variable public and exposing it
  • Using property without SerializeField
  • Forgetting to add [SerializeField]
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard