I have a class (GameManager) that centralise a lot of features, and makes the link between the gameplay part with the animation, board logic etc…
This class has to be called a lot of time, and need to be referenced in various places.
I don’t know how to handle that. I currently have a reference of it in a lot of my other classes, and I manually assigne it everytime. But repetition is often a deadgiveaway. There is probably a better way to handle that.
I was thinking about adding a static reference inside GameManager to the current instance.
And inside of my classes, I would do GameManager.instance.GetCameraManager().DoStuff()
The .instance feels a bit ugly, and I was thinking about making the whole class functions statics, as I’ll always need one GameManager and no more. But I’m not sure how to assign gameobject to it. Can static fields of script be serialized somewhere in Unity ? Static propreties that are linked to scene element is a bit weird itself, so i’m also unsure of this solution. I’ve heard about ISerializationCallbackReceiver, maybe I can create a element in my scene that will setup my GameManager properties when loaded.
Is there something I missed or am I heading in the right direction ?
These are pure-code solutions, do not put anything into any scene, just access it via .Instance!
If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:
public void DestroyThyself()
{
Destroy(gameObject);
Instance = null; // because destroy doesn't happen until end of frame
}
There are also lots of Youtube tutorials on the concepts involved in making a suitable GameManager, which obviously depends a lot on what your game might need.
Having to call .instance is part of using the singleton pattern.
The singleton pattern causes tight coupling between classes. One way of decoupling could be using scriptable objects. An example is from Ryan Hipple’s video about scriptable objects.
Personally I try to avoid using the singleton pattern as much as possible. But if you find it easier to manage your project that way, that is completely up to you. It depends on your personal preference.
The scriptable object solution can potentially introduce a new problem. Asset management and serialization of them. When the project grows larger the management of all these scriptable objects may get messy.
Also adds limitations when you’re using Addressables. You have to separate addressable scriptable objects and the ones that are built with the project. They’re separate instances.
if prefabA is loaded through addressables and references player health and you have a scene built-in with a reference to that same player health then you get 2 different player health object instances. One from addressables and one built-in.
It’s kinda complicated.
This is a huge limitation. Worked on a project the last few years with an enormous web of SOs used to configure all the different subsystems, bringing it all together nicely at runtime. This “context” object lived on just about EVERYTHING in the project.
We dropped in Addressables and then all of a sudden we had to completely revisit our SO config system. If we had simply used a service locator pattern from the start (eg, lazy-loaded singletons), nothing would had needed to change.
What I did in our project was move every scene to addressables. Begin with a built-in bootstrap scene that only loads in an Addressable bootstrap scene. From there we update and continue.
All scriptable objects created are under 1 folder, so we dragged in the folder into an Addressable group. So we don’t get any duplicates.
So any references to scriptable objects in the addressable scenes are now referencing the scriptable objects from addressables.