Statics Best Practice

I’m setting up the management system for a game project I’m working on, which at its core has a GameManager class which carries across all scenes via singleton.
Within each scene is a LevelManager class which holds properties specific to that level (player start position, etc.). A reference to the current LevelManager is added to the GameManager when a scene launches, and is set to null when the scene changes.
I’m currently assigning the LevelManagers to a Static property, but I’m wondering if there is any point to doing so if I’m going to reference the GameManager instance anyway. Do people have an opinion on whether it is better to keep it as a static or just use a public property?

 public class GameController : MonoBehaviour
    {
        public string helloWorld = "Hello World";
    
        private static GameController _instance;
        public static GameController Instance
        {
            get
            {
                return _instance;
            }
        }
    
        private static LevelController _currentLevelController;
        public static LevelController currentLevelController
        {
            get
            {
                return _currentLevelController;
            }
        }
    
        void Awake()
        {
            if (_instance == null)
            {
                _instance = this;
                Debug.LogWarning("GameController assigned on awake.");
            }
        }
    
        public void AssignLevelController(LevelController levelControllerInstance)
        {
            Debug.Log("LevelController unassigned: " + currentLevelController);
            _currentLevelController = levelControllerInstance;
            Debug.Log("LevelController assigned: " + currentLevelController);
        }
    }
    
    
    public class LevelController : MonoBehaviour
    {
        private GameController gameController;
        public string property = "Property Recieved!";
    
        void Awake()
        {
            gameController = GameController.Instance;
            gameController.AssignLevelController(this);
        }
    }
    
    
    public class GetLevelControllerProperties : MonoBehaviour
    {
        private LevelController levelController;
    
        void Start()
        {
            levelController = GameController.currentLevelController;
            StartCoroutine(GetProperty());
        }
    
       IEnumerator GetProperty()
        {
            yield return new WaitForSeconds(5f);
    
            Debug.Log(GameController.Instance.helloWorld);
    
            Debug.Log(levelController.property);    //Has to access through the GameController
        }
    }

Don;t use singletons! They are the DEVIL! :stuck_out_tongue: Unity’s scriptable objects make singletons unnecessary, the pattern itself it not too bad, but how they are abused. You have a GameManager singleton that has don’t destroy on load and I bet tons of unrelated data, just used to save across scenes. ScriptableObjects don’t live in scenes so you could use one as a GameManager, but that is still a big monolithic class, which is really the root to all the problems. You need to use scriptable object architecture, make scriptable object variables that you can plug in anywhere.