Learning to use Unity and all of its different features can be a long and difficult process. This is true for whether you are developing a game or are using Unity for data visualization. At some point, you’ll get into a situation where you will want to tweak values through the Unity Inspector. Setting up a script for this with some public variables is easy. Yet, this is not without danger. Let’s see how you can improve your code in Unity by using the SerializeField attribute.

How Public Fields Are Commonly Used in Unity
First, let’s dive into an example to demonstrate why public fields are potentially dangerous and thus bad. Below you can find a simple snippet of code that describes a common Player class by beginners. When the script starts, it will display a message to the Unity Console with its current health. Notice how the health variable is a public field so it will automatically show up in the Unity Inspector. Any developer can now tweak the value for health in the level. This seems quite harmless, right?
Player.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public int health = 100; void Awake() { Debug.Log("My Health is " + health); } }
As you may have guessed, this actually is bad. This is because you are directly exposing the health variable to other classes. Any class wanting to do something with player health now has total freedom. At this point, you might not see why this could be a problem. So, let’s see what happens if we continue to develop our game by introducing a Bullet that damages the player on impact.
Bullet.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { public int damage = 1; void OnCollisionEnter(Collision collision) { Player player = collision.transform.GetComponent<Player>(); player.health -= damage; } }
The Hidden Dangers of Public Fields
Delegating the Implementation
As can be seen above, we now have a bullet script that decreases the health of the Player if it collided with the bullet. And here we are… This is where the danger is. So what is it? Decreasing the health of the Player class is none of the responsibility of the Bullet class. In other words, the Bullet class should not need to know how the Player decreases its health, only that it needs to be done. By creating a public field you are in danger of delegating an implementation to another class that has no need for it.


Increased Code Duplication
Another problem with using a public field for health is that you are duplicating code. Let’s say we continue to develop our game by adding a lava floor that damages the player when it steps on it. Similarly to the Bullet, we will need to decrease the Player health when a collision occurs In this case, both classes attempt to decrease the Player health in a very similar way. And what about adding a health pickup to our game? Clearly, it’s better to write a function that handles health changes for all objects that change the Player health. Simply put, exposing a public field increases the likelihood of code duplication.
Improve Your Code in Unity Using the SerializeField Attribute
By now you might be thinking it is probably good idea to make the Player health field either private or protected. Next to that, you might be considering to wrap the damage the player receives into a function. Yet, how can you still tweak the health field of the Player through the Unity Inspector if it’s not public? Actually, this is really simple. By adding the SerializeField Attribute to any private or protected field it will automatically appear in the Unity Inspector. Adding this attribute is easy and forces you to improve your code in Unity.
Player.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { [SerializeField] private int health = 100; void Awake() { Debug.Log("My Health is " + health); } public void ChangeHealth(int change) { health += change; } }
In the code above, we added the SerializeField Attribute to the Player health field. Through Attributes, you can add extra meta information to types, methods and fields in C#. You can see it as giving Unity extra hints about a certain type or field.
Next to that, we added a function that changes the player health by a given amount. Both the Bullet and Lava class can call this new ChangeHealth method, rather than directly changing the health in their respective classes. This is also great if you want to implement status effects. Classes like bullet only need to know how much damage they do to the Player. What the eventual result of that damage is can be determined in the Player through the ChangeHealth method. This way, classes adhere more to the Single Object Responsibility Principle often found in Object Oriented programming.
Summary
What we hope you have learned from this article:
- A public field will automatically show up in the Unity Inspector, allowing you to tweak the value
- By creating a public field, you are in danger of delegating an implementation to another class that has no need for it.
- By exposing a public field you are increasing the likelihood of code duplication.
- By adding the SerializeField Attribute to any private or protected field it will automatically appear in the Unity Inspector.
- Through attributes, you can add extra meta information to types, methods and fields in C#

Conclusion
By now we hope you have learned why using the SerializeField Attribute can help improve your code in Unity. We have shown you the hidden dangers of making your fields public and why it is better to make them either protected or private. Next to that, we have shown you how you can still edit your non-public field in the Unity Inspector using the SerializeField Attribute.
Further Reading
If you found this interesting, you might also like the following articles:
