I want to create a utility class that will, among other things, return a cached reference to the main camera. Is the below code correct? My concern is that I’m doing it wrong and that FindGameObjectWithTag is being called each and every time the getter is referenced.
using UnityEngine;
public static class Utils
{
public static Camera MainCamera { get; } = Camera.main;
}
Let me first offer you congrats on a great attempt!
But alas, there’s a bunch of lifetime and timing subtleties that cause problems with the above approach.
First off, static classes get new-ed up at some random point in time. No telling if Unity is even fully up and running with a scene, or that there is a main camera. That means this initialization will probably not work.
Second, when you change scenes, this will keep returning the old camera from before, if it was ever able to find a legal one in the first place.
So what you want is a check and possible get, then return:
static Camera _mainCamera;
public static Camera MainCamera
{
get
{
if (!_mainCamera)
{
_mainCamera = Camera.main;
}
return _mainCamera;
}
}
This won’t get invoked in any way until you call it from one of your Monobehavior instances, plus if you switch scenes, the previous camera will now be destroyed, so this will seek a new main camera.
Sometimes… really the main thing I don’t like about the above is now all the code will have that one common dependency, a dependency that doesn’t really add much value. For something as simple as getting the main camera, I usually just do it locally, cache it locally done.
If I do use common utility classes it is generally for things that add a bit more value, like a specialized GameObject finder, or something else with a little bit of valuable logic that I don’t want to copy/pasta around everywhere.