Watching the lecture of why to use Persistent Objects instead of singletons I do not feel this solves anything. Having a Ambient Audio Player Behaviour in Don’tDestoryOnLoad is not accessible from another script unless you use find object (what I consider bad practice and bad for optimisation). The Class is not static so you cannot access it that way and it has no reference in PersistentObjectSpawner to get a reference there. How on earth would I access this script from another script and use the FadeNewMusic method ??
You’re basing a lot on this assumption.
It doesn’t. Depending on how it’s done, it basically turns a persistent object into a defacto singleton (not quite, but basically).
You already have the answer. It’s FindObject OfType, by tag etc. I’m guessing the only thing that’s holding you back is that pesky assumption.
I’m going to suggest that for now, you stop worrying about optimisation and just take in the information the teachers are offering. Later on, you’re more likely to have the required knowledge on better coding practices. You’re worried about solving a problem that might not need to be solved. Down the track, you’re likely to have the experience to know to do it a different way, but until then, keep adding tools to your toolbelt.
It is technically just another form of singleton
You would use FindObjectOfType, or create a custom tag and use GameObject.FindWithTag()
One could debate whether it is better than a standard Singleton or not. It’s primary strength is when you have several objects that need to be persistent across multiple scenes, and it absolves these classes from having to impement the Singleton pattern (sticking to the Single Responsiblity Principle).
Thanks both for responses!
I agree when starting out in Unity using FindObjectOfType or FindObject is fine, but I am looking for more of an in depth and advanced version then? Find can be used for smaller projects/prototyping but I would never allow a junior or Mid to include this into a codebase at work when reviewing their work because it has to go though every single component on every single game object when another method could be done (simply caching the reference then moving it to DontDestoryOnLoad for this videos example). This would be not acceptable anywhere out of start, and even then I would try to use another design pattern than having to resort to Find.
So really this video needs to include the FindObjectwithTag / FindObjectOfType included to make sense, that’s fine. Thanks for help!
You can cache them or use statics but they’re both fraught with potential issues that can be tough to debug if things go wrong. But you can do it if you feel you’re ready for more advanced things.
You can use Scriptable Objects, you could use JSON to save/load, resources, connect to a database, stream… there are so many more options. What’s best depends on your needs. That all being said, FindObjectOfType is probably going to be faster than most of what I’ve suggested, so you’re back to “starting out in Unity” techniques. If you feel game, you could even try dependency injection.
I love using scriptable events (using scriptable objects to use events to connect everything up) to use the observer pattern. It’s a nice solve for what you’re looking at. It’s kind of intermediate level, so that’s usually a bit more than most are looking to deal with, but it’s a great solution if you’re brave enough. If you want to learn more, there’s a video called “Overthrowing the tyrany of monobehaviour” which first introduced me to the concept. There’s a few other Unity videos that go further into it but I don’t remember what they’re called.
I’m warning you. In the end, you’re going to choose FindObectOfType. It’s way better than most solutions I see people coming up with that often involve all sorts of cyclical dependencies.
Most of the time you wouldn’t do it outside start/awake, but there are times where you just don’t have better options. So long as it isn’t in a heavy repetitive loop at a wrong time, who cares?
Isn’t that akin to not allowing foreach as it goes through all iterations of a collection. To me, it feels like a rule for the sake of having a rule to make the powers that be feel all mighty and powerful, rather than a rule for a real reason.
Use the best tool for the job. Would you require a trades person to use a sledge hammer to hit a tiny nail?
Design patterns are there as tools to help you solve problems that programmers need to solve. You don’t usually run to a design pattern to get out of using a simple built in function.
Adding my two cents.
I rather use FindObject
than recurring to singletons. The main reason is that FindObject
can be very easily solved with a loading screen, that’s something all games already need. I honestly don’t get why people get so scared by that method, it’s slow, yes, but it’s not even that slow and you’ll only use it during Awake
, it’s not something that will slow down your code all the time.
In the other hand, singletons cause way too many issues for me to even consider them; they create way too many dependencies, your code cannot be decoupled by default since you have this global functionality that a lot of classes require and need to know about, if your code is too dependent on a singleton it can cause racing issues making debugging a complete a nightmare, it’s the worst pattern for beginners, it’s way too powerful, very easy to use and understand, a lot of beginners end with the biggest spaghetti you’ll ever see thanks to that pattern (true story), and finally, if working with a team, it must be a consensus type of thing, it’s not something you can use just because you felt the need to.
That’s why singletons are at the bottom of my toolkit, I only use them when they are absolutely necessary.