Course contentsShow
← Unity Game Development
Lesson 500 of 8287. Advanced Game ArchitectureFree lesson

Refactoring Monolithic Systems into ScriptableObject Architectures

Students will demonstrate the ability to identify hard dependencies in existing code and refactor them into a clean, modular ScriptableObject-based architecture.

In this lesson, you will learn how to break down rigid, "all-in-one" manager scripts by offloading their state and logic into modular ScriptableObject assets.

Identifying the Monolith

A monolithic system typically manifests as a single "God Script" (e.g., GameManager.cs) that holds everything: player health, inventory lists, input logic, and sound effects. While convenient initially, this creates hard dependencies; if the GameManager changes, every other script breaks. To refactor this, we look for data that should be persistent and logic that should be independent.

From Monolith to Architecture

The goal is to move state into ScriptableObject "Variables" or "Sets" and offload logic into "Actions" or "Strategies." Instead of the Player script calling GameManager.Instance.UpdateHealth(10), we flip the relationship. The Player now references a FloatVariable asset.

Consider this refactoring:

The Monolith (Before):

public class GameManager : MonoBehaviour {
    public float playerHealth = 100f; // Hard-coded in one place
    public void TakeDamage(float amount) { 
        playerHealth -= amount; 
        // Direct coupling to UI, Audio, etc.
    }
}

The Decoupled Version (After): We extract the health into a FloatVariable ScriptableObject. Now, the Player and UI both reference the same asset independently.

[CreateAssetMenu]
public class FloatVariable : ScriptableObject {
    public float Value;
}

public class HealthComponent : MonoBehaviour {
    public FloatVariable health; // Asset injected via Inspector

    public void TakeDamage(float amount) {
        health.Value -= amount; // Logic is now data-driven
    }
}

Why This Matters

By extracting state into ScriptableObjects, you remove the need for FindObjectOfType or static singletons. Systems no longer need to know the GameManager exists. The HealthComponent simply needs a FloatVariable. You can now swap that variable for a "BossHealth" or "PlayerHealth" asset in the inspector without changing a single line of code. This modularity allows your systems to be tested in isolation and enables designers to tweak game data while the game is running without fearing that they’ll break the underlying logic.

Key Takeaway: Refactoring to a ScriptableObject architecture means shifting from "one object knows everything" to "many objects share data through decoupled references."