How to implement a Unity solid Game Data Architecture

There is a common Unity programming challenge in all genre of games: Implement variables and game data that you can initialise, load, save and most important, use in any part of your code easily.

Game information like health, score, level, achievements, etc… are present in any game, and must be access, manipulated and stored all over the game programming.

// One static class enable you to access the variables and functions inside it from any place on your code using: GameData.Health
public static partial class GameData
{

private static string healthKey = "health"; // Key name to store health
private static int initialHealth = 10; // Initial value, before any save
private static int maxAlowedHealth = 100; // Initial value, before any save
private static int health = 0; // Internal variable to store the value
private static bool healthFirstUse = true; // Use saved dat only once per launch

// Here is the real deal. A static get/set function that do everything
public static int Health {

    // When use like: int value = GameData.Health;
    get {
        if (healthFirstUse) {  // Each new game launch this will be true
          if (PlayerPrefs.HasKey (healthKey)) {      // Check if it is saved already
            health = PlayerPrefs.GetInt (healthKey);  // If there is a saved value, get it.
          } else {  // If there is no saved data
            health = initialHealth;                        // Use the initial value
            PlayerPrefs.SetInt (healthKey, initialHealth); // Save it
            PlayerPrefs.Save ();
          }
          healthFirstUse = false; // Avoid retrieve save value after first launch
        }
        return health; // Return the value
    }

    // When use like: GameData.Health += 10;
    set {
        health = Mathf.Clamp(value, 0, maxAlowedHealth); // Avoid any value out of range
        PlayerPrefs.SetInt (healthKey, health); // Save the value for future launches
        PlayerPrefs.Save ();
    }
  }
}