Tired of waiting for Unity to reload script assemblies every time you run your game? You can turn that off:
@peterdrake Except then static variables persist between sessions, which can easily break poorly-implemented singleton patterns. Be *very* careful.
If your builds are taking a long time, I highly recommend letting unity refresh the Library folder (just close Unity, delete the library folder from your project, and re-open unity). It'll take Unity a while to rebuild that folder, but then script builds should be *much* faster for a while.
@LouisIngenthron Can you say more about properly implementing singletons? A web search reveals a deep rabbit hole on this, but all of them use static variables.
@LouisIngenthron Good stuff -- thanks!
Two questions:
1) A "traditional" singleton would provide a static GetInstance method, and keep the constructor private, to prevent a second instance from ever being created. That won't work here because of the way Unity creates GameObjects (and their components), right?
2) In Destroy, why check if Singleton is null? If it's == this, we already know it isn't null ... right?
@LouisIngenthron If this was already destroyed, could the Destroy method still run?
It's sort of a race condition, so I'm not sure how to set up a test.
@peterdrake No, I don't think so. It would only be to check if a singleton from a previous execution context was still stored in the static reference.
But it's worth noting that there are a number of places where OnDestroy may *not* be called (mostly in-editor, not in-built-game, such as hard exits).
@LouisIngenthron I've almost got it, but can you walk me through a situation where
Singleton != null && Singleton == this
has a different value from:
Singleton == this
@peterdrake It shouldn't, so long as unity's implementation of (Singleton == this) has its own null-check first, which it probably does, but I'm not sure.
So, the situation I'm concerned about would be that Singleton references a destroyed object. Running (Singleton == null) checks if it's null *or* destroyed, which prevents the second check. But I don't know if (Singleton == this) will also break out if it's null or if it will try to run a comparison op between a live object and a destroyed one (which would throw an error).
In other words, it's mostly just me being paranoid and defensively coding.
@LouisIngenthron Ah, I get it. Thanks!
@peterdrake On 1, correct. That's why I usually make the singleton property a public get but a private set. With the pattern above, that achieves the same goals.
On 2, it's to specifically use Unity's overloaded null checks to make sure it's not pointing to a dead/destroyed reference before checking equality. I'm not sure if the straight equality check does that, so I added a null check as a short-circuit.