The imported system already has this fix in LoadLastScene()

If people find this lesson to be confusing and complicated, it is because hunting down race conditions (when you have observed a bug in your code that you have determined to have been caused by one) is a complicated things and the causes for race conditions can be confusing and complicated. It’s just the nature of this type of bugs…

The whole thing Sam is showing in this lecture is thinking about your code, determining what could be possible causes that have caused an error that must have been caused by some sort of race condition (in the sample we have the RestoreState() which is by definition supposed to be run exactly between Awake() and Start(), so if a component is cached in Awake() but missing inside of RestoreState() that’s a clear sign of a race condition having fired), and then backtracking from there the possible code paths that get to that point until finding one possible way that would lead to that deadly inverted order of execution that make RestoreState() getting called before Awake() was.

And the real crux is that even following the order that Brian is preaching meticulously about the order of initialization in Awake() and using only in Start() won’t really help you in this particular case.
A band-aid option would be not to rely on cached components inside RestoreState() at all (and possibly caching it inside of the method as well in case it makes sense), but having it fixed in the saving system (which was the place the race condition fired) is a much better solution. It fixes it once and for all, and keeps the RestoreState() impementations clean.

Your absolutely right, race conditions can be very tricky to hunt down, and sometimes the fixes for a race condition lead to more race conditions. I can recall a few times that students race conditions still weren’t solved by LazyValue and utilizing Awake() for caching. Usually it was a poorly written LazyValue or people still trying to access external classes within Awake() even though they cached. For extra fun, try a LazyValue whose Init() is self-referential… No fun at all overflowing memory, especially if you’re on a 64 bit system with 32 gig of memory… you get to wait a while before it crashes.

When you do get it right, however, well architected code beats putting corner cases in troublesome events any day of the week.

Privacy & Terms